Compare commits

...

448 Commits

Author SHA1 Message Date
github-actions[bot]
7bb281d5c5 [create-pull-request] automated change (#2316)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-03-01 12:31:58 -06:00
A. Rager
214feb1f21 Add Hardware: BetaFPV 900 Nano TX (#2249)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-03-01 08:36:25 -06:00
Ben Meadors
d17aafa91a Trying to debug transient "disconnects" in iOS (#2312)
* Add back lines from original Adafruit example sketch

* Stop advertising debug message

* Yank it
2023-03-01 08:35:52 -06:00
code8buster
2fe5eae183 Fix overlapping of GPS message on screen carousel #1 (#2314)
* Fix overlapping of GPS message on screen carousel #1

* Any reason we shouldn't display this on a RAK w/ E-ink or similar non-PMU equipped boards?

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-03-01 08:34:07 -06:00
Manuel
9008c75517 Fixed: Tlora-t3s3-v1 SX1262 firmware reboots continuously (#2308) (#2315) 2023-02-28 07:45:10 -06:00
GUVWAF
408c555f0f Add airtime of current received/transmitted packet to nextTx time of all pending retransmissions (#2309)
To avoid unnecessary retransmissions when sending them too early

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-02-25 19:51:38 -06:00
github-actions[bot]
c9ae90f03c [create-pull-request] automated change (#2306)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-02-24 15:07:39 -06:00
Ben Meadors
fbfd0f12b5 Change to 5 minutes for Garth's sanity 2023-02-24 12:49:10 -06:00
Ben Meadors
9650adb616 Set reasonable defaults for sensor role and adjust packet priority (#2305) 2023-02-24 11:25:50 -06:00
Thomas Göttgens
fab5e4c5cc potential fix for Range Test Leak. Poking around in the dark. 2023-02-23 22:19:23 +01:00
Ben Meadors
46fa08dc33 Air quality specific prefs (#2303) 2023-02-23 13:05:24 -06:00
github-actions[bot]
05b1fc83bd [create-pull-request] automated change (#2300)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-02-22 16:16:38 -06:00
Thomas Göttgens
9fc18c2a19 Merge pull request #2295 from meshtastic/2228-bug-heap-leak-in-rangetestmodule
tryfix #2228 as suggested by @mverch67
2023-02-21 20:40:20 +01:00
Thomas Göttgens
d830398fc5 Check if there's something there before we free it 2023-02-21 20:01:56 +01:00
Thomas Göttgens
2e80a4ed87 tryfix #2228 as suggested by @mverch67 2023-02-21 14:53:27 +01:00
Ben Meadors
e1924f188f Remove extra 2023-02-21 07:18:08 -06:00
github-actions[bot]
732caff2b8 [create-pull-request] automated change (#2294)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-02-21 06:23:02 -06:00
Ben Meadors
c60c00ba85 Add da explora 2023-02-20 16:23:02 -06:00
GUVWAF
83e6cea280 RadioLib's startChannel returns LORA_DETECTED for SX126x and SX128x (#2293) 2023-02-20 14:11:54 -06:00
Ben Meadors
f8498ba03f Trunk fix 2023-02-20 12:33:01 -06:00
Ben Meadors
f83adf1796 Trunk fmt 2023-02-20 10:05:11 -06:00
Krezalis
73c1c5913b Update Screen.h (#2285)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-02-20 10:03:32 -06:00
Krezalis
fd1c54fd15 Add Ukrainian symbols (#2286)
* Update Screen.cpp

* Add files via upload

* Update Screen.cpp

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-02-20 10:03:13 -06:00
GUVWAF
95bbcd2cb7 Use LORA_DIO1 as RadioLib GPIO for SX127x chips (#2290)
* When channel is active, first try receiving that packet
Afterwards we'll try transmitting again

* Remove setStandby in startSend
Already done in isChannelActive()

* Set LORA_DIO1 as RadioLib GPIO for SX127x

* LORA_DIO1 for Heltec v1, overlaps with GPS_TX
Set to RADIOLIB_NC for now

* If receive was not successful, startReceive doesn't trigger the interrupt
So we have to go back to transmitting anyway

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-02-20 07:40:44 -06:00
Ben Meadors
187f3969c2 Missed a reference 2023-02-20 07:22:33 -06:00
Ben Meadors
15458309f8 Remove pico from build for now 2023-02-20 07:20:14 -06:00
Ben Meadors
253d133319 Merge pull request #2287 from neilhao/master
Nano G1 Explorer
2023-02-18 19:06:37 -06:00
Ben Meadors
7264621149 Don't auto set to default primary channel 2023-02-18 18:32:46 -06:00
Neil Hao
27d93c5f66 Update extensions.json 2023-02-18 05:00:43 +08:00
neil
b33632f21a 'nano-g1-explorer' 2023-02-18 04:49:37 +08:00
Ben Meadors
89f06d6b40 Merge pull request #2283 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2023-02-17 06:52:37 -06:00
thebentern
7102fec7b3 [create-pull-request] automated change 2023-02-17 12:50:01 +00:00
Ben Meadors
c39645419a Merge pull request #2279 from meshtastic/preamble-halving
Preamble change
2023-02-16 20:42:05 -06:00
Ben Meadors
6f4ac904a5 Merge branch 'master' into preamble-halving 2023-02-16 19:26:48 -06:00
Ben Meadors
643237162e Regen protos 2023-02-16 19:26:21 -06:00
Ben Meadors
cef11968eb Merge branch 'master' into preamble-halving 2023-02-16 19:09:47 -06:00
Ben Meadors
5c72967aa5 Merge pull request #2278 from meshtastic/metadata-phone-api
Add metadata to phone api want config messages
2023-02-16 19:09:37 -06:00
GUVWAF
8aede61adb Fix setting preambleLength for SX127x
Don't set currentLimit, it is set automatically in begin()
2023-02-16 20:58:10 +01:00
Ben Meadors
07b90a61e1 For science 2023-02-16 13:51:20 -06:00
Ben Meadors
221a145d2d Whoops 2023-02-16 12:58:54 -06:00
Ben Meadors
b3fac71a8d Missed some stuff 2023-02-16 12:52:03 -06:00
Ben Meadors
2e6e0644d4 Move it around and kill old device metadata gen 2023-02-16 12:18:27 -06:00
Ben Meadors
b78e0dce46 Merge branch 'master' into metadata-phone-api 2023-02-16 10:21:31 -06:00
Ben Meadors
3ae1fdf661 Add metadata to phone api want config messages 2023-02-16 10:21:03 -06:00
Ben Meadors
cbfa2dcc0e Merge pull request #2276 from GUVWAF/NodeInfoSanityCheck
Sanity check for sending NodeInfo
2023-02-16 10:20:16 -06:00
Ben Meadors
2aabeafefe Merge branch 'master' into NodeInfoSanityCheck 2023-02-15 12:42:39 -06:00
GUVWAF
b7895f7038 Sanity check for sending NodeInfo
Don't send it if we've done so less than 1 min. ago
2023-02-15 19:31:09 +01:00
Ben Meadors
3f4780479f Merge pull request #2274 from GUVWAF/roleFixes
NodeInfo fixes for other roles
2023-02-11 19:25:04 -06:00
GUVWAF
5ca3d9169a Only set node_info_broadcast_secs when not a Router 2023-02-11 17:17:11 +01:00
GUVWAF
c834252f1c Check if nodeInfoModule exists (e.g. for Repeater) 2023-02-11 17:16:48 +01:00
GUVWAF
16852da8d4 Set node_info_broadcast_secs to 3 hours instead of default_broadcast_interval 2023-02-11 15:58:26 +01:00
GUVWAF
2d2633d4cf Increase default NodeInfo broadcast to 3 hours 2023-02-11 15:58:26 +01:00
GUVWAF
5f28ef6814 When hearing a node we don't know, send NodeInfo and ask for response 2023-02-11 15:58:26 +01:00
GUVWAF
5cadcd355f Send DeviceTelemetry only after NodeInfo is sent 2023-02-11 15:58:26 +01:00
GUVWAF
40d98b9d8d Merge pull request #2272 from GUVWAF/portduinoDeviceTelemetry
Enable DeviceTelemetry on Portduino
2023-02-11 15:21:24 +01:00
Ben Meadors
0f47584a50 Merge branch 'master' into portduinoDeviceTelemetry 2023-02-11 06:56:23 -06:00
Ben Meadors
dbb827e5e0 Merge pull request #2271 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2023-02-11 06:43:54 -06:00
Ben Meadors
f95061b965 Merge branch 'master' into create-pull-request/patch 2023-02-11 06:43:46 -06:00
GUVWAF
4061870841 Don't need a Portduino guard clause here as it will not be compiled 2023-02-11 12:04:53 +01:00
GUVWAF
abf3a5840b trunk fmt 2023-02-11 11:46:54 +01:00
GUVWAF
7063acdda6 Ignore syslog on portduino
Breaks when running since mesh/http is not compiled
2023-02-11 11:32:10 +01:00
GUVWAF
97c1cf628a SimRadio in separate thread
To use notifyLater when transmitting, fixes packetPool issues
2023-02-11 10:34:08 +01:00
GUVWAF
03f584a5ab Add HAS_TELEMETRY to portduino 2023-02-11 10:09:48 +01:00
GUVWAF
680550b76c Add HAS_SENSOR flag
To separate DeviceTelemetry and EnvironmentTelemetry
2023-02-11 10:08:25 +01:00
GUVWAF
a280d7f796 Guard simulator handling with HAS_RADIO flag 2023-02-11 10:00:19 +01:00
Ben Meadors
09f2ea8938 Portduino isn't extra. It's extra special 2023-02-10 07:47:43 -06:00
thebentern
fcbeeac28f [create-pull-request] automated change 2023-02-10 13:30:51 +00:00
Ben Meadors
7100416142 Add short_name 2023-02-09 19:32:32 -06:00
Thomas Göttgens
83e309f3bf label boards as secondary to split the core firmware archive by support level.
Ref: https://docs.platformio.org/en/latest/scripting/examples/platformio_ini_custom_options.html
2023-02-10 01:35:25 +01:00
Thomas Göttgens
dc6f6af7fb Update to Espressif32 Platform 6.0 and ESP-IDF 5.0 2023-02-10 00:21:15 +01:00
Ben Meadors
aaba99f792 Add changed back 2023-02-09 10:48:17 -06:00
Ben Meadors
4375a0101e Remove setOwner's business logic for licensed operation 2023-02-09 08:58:28 -06:00
Ben Meadors
b1677e0312 Rebroadcast mode to local_only for hams 2023-02-09 07:51:41 -06:00
Ben Meadors
0c240a1dff Merge pull request #2266 from meshtastic/nodeinfo
Ham mode should broadcast in plaintext and nodeinfo every 10 minutes
2023-02-08 21:07:17 -06:00
Ben Meadors
b24376b1fc Well it helps if I commit the thing 2023-02-08 20:21:33 -06:00
Ben Meadors
bcaf834853 Interval or default 2023-02-08 18:04:21 -06:00
Ben Meadors
1c3970efab Default node info broadcast secs for ham operation 2023-02-08 15:36:23 -06:00
Ben Meadors
79850c6d03 Set open psk for ham mode 2023-02-08 15:29:33 -06:00
Ben Meadors
440074af62 Merge pull request #2263 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2023-02-07 20:03:21 -06:00
thebentern
dc23096723 [create-pull-request] automated change 2023-02-07 21:59:05 +00:00
Ben Meadors
3209aeabb8 Merge pull request #2262 from GUVWAF/tryFixPortduino
Next try fix Portduino
2023-02-07 13:52:39 -06:00
GUVWAF
42b496b0db PIC 2023-02-07 20:12:12 +01:00
GUVWAF
a5b99ee5d5 Try other location 2023-02-07 20:05:40 +01:00
GUVWAF
4a0c341438 Make Portduino build again 2023-02-07 19:40:15 +01:00
Ben Meadors
afc75b2552 Can't find where this was included 2023-02-07 07:43:09 -06:00
Ben Meadors
9522d4d2f5 Make a pie? 2023-02-07 07:17:32 -06:00
Ben Meadors
7ddd8c9930 Update protobufs to release version 2023-02-07 07:06:24 -06:00
Thomas Göttgens
23e1c0b7a8 Merge pull request #2168 from meshtastic/rsyslog-client
Add RSYSLOG Support to TCP Firmware
2023-02-07 01:58:45 +01:00
Thomas Göttgens
631699bfd7 Merge branch 'rsyslog-client' of github.com:meshtastic/firmware into rsyslog-client 2023-02-07 01:31:18 +01:00
Thomas Göttgens
4ac0de21ab great, the ONE time i remember trunk fmt i forget to cppcheck ... 2023-02-07 01:30:55 +01:00
Thomas Göttgens
4ede8ab9de Merge branch 'master' into rsyslog-client 2023-02-07 01:08:24 +01:00
Thomas Göttgens
b952c35da6 eliminate main source of multiline logging 2023-02-07 01:02:51 +01:00
Thomas Göttgens
a3dbac73fe trunk fmt 2023-02-05 09:06:57 +01:00
Thomas Göttgens
fb611ef986 fix time display 2023-02-05 09:06:57 +01:00
Thomas Göttgens
b07904fe77 Merge remote-tracking branch 'remotes/origin/master' into rsyslog-client 2023-02-05 01:21:30 +01:00
Ben Meadors
9e1f7c4f56 Merge pull request #2253 from meshtastic/set-ham-mode
Set ham mode admin message
2023-02-04 18:07:10 -06:00
Ben Meadors
af11c5aa80 Merge branch 'master' into set-ham-mode 2023-02-04 18:07:02 -06:00
Thomas Göttgens
829318046a rsyslog is working 2023-02-05 00:11:00 +01:00
Ben Meadors
405430fd96 Whoops 2023-02-04 15:15:32 -06:00
Ben Meadors
8630e420a7 Merge pull request #2250 from meshtastic/bug-2084
Change LED Blink time in light sleep to 100ms
2023-02-04 15:11:51 -06:00
Ben Meadors
b70af5cc78 Set ham mode admin message 2023-02-04 15:11:36 -06:00
Ben Meadors
b9516154d4 Merge branch 'master' into bug-2084 2023-02-04 14:34:59 -06:00
Ben Meadors
21443dab05 Merge pull request #2252 from meshtastic/air-quality
Initial air quality telemetry feature
2023-02-04 14:25:39 -06:00
Ben Meadors
1748db3160 Init struct 2023-02-04 13:35:02 -06:00
Ben Meadors
d83a0b1818 Initial air quality telemetry feature 2023-02-04 13:07:14 -06:00
Thomas Göttgens
18442816ef trunk fmt 2023-02-04 17:15:36 +01:00
Thomas Göttgens
c28d469fc6 Change LED Blink time in light sleep to 100ms 2023-02-04 17:13:38 +01:00
Thomas Göttgens
d97a09ba1f add DEBUG_HEAP_MQTT flag to send stats info to mqtt. Used to graph these values over time. Turned off for regular builds 2023-02-04 14:56:04 +01:00
Thomas Göttgens
22500a6c34 tryfix for #2242 2023-02-04 11:36:35 +01:00
thebentern
bba4de3ec7 [create-pull-request] automated change 2023-02-03 22:44:33 +01:00
Ben Meadors
1a7991c606 Why would you even 2023-02-03 15:08:49 -06:00
Ben Meadors
490ef459e5 Merge pull request #2247 from meshtastic/connectionstatus-and-augment-metadata
Connectionstatus and augment metadata
2023-02-03 14:27:25 -06:00
Ben Meadors
40b7d783ed Merge branch 'master' into connectionstatus-and-augment-metadata 2023-02-03 14:27:18 -06:00
Ben Meadors
6a2583e872 Trunk you mothertrunker 2023-02-03 14:10:19 -06:00
Ben Meadors
3a3451129a Init gooder? 2023-02-03 13:59:54 -06:00
Ben Meadors
81d2486cf4 Init defaults 2023-02-03 13:17:39 -06:00
Ben Meadors
9d420f403a Try this 2023-02-03 13:05:25 -06:00
Ben Meadors
c82d1de9ce Check 2023-02-03 12:43:16 -06:00
Ben Meadors
9a950afd2a Trunk fmt 2023-02-03 11:30:36 -06:00
Ben Meadors
ab77772e0c Bugger 2023-02-03 11:11:09 -06:00
Ben Meadors
ac90c27ae8 Macros 2023-02-03 11:03:12 -06:00
Ben Meadors
d6de042783 Assume portduino is always connected 2023-02-03 11:00:05 -06:00
Ben Meadors
2b15d951cf Trunk 2023-02-03 10:50:03 -06:00
Ben Meadors
0414ca2dc0 Fixed it 2023-02-03 10:49:44 -06:00
Thomas Göttgens
7a50934185 change time display to relative for rx messages 2023-02-03 17:45:12 +01:00
Ben Meadors
1fa2ca6a14 Trunk it 2023-02-03 09:50:49 -06:00
Ben Meadors
51521462c4 Eh 2023-02-03 09:18:53 -06:00
Ben Meadors
4aaf162700 Getting tired of looking at code 2023-02-03 09:17:28 -06:00
Ben Meadors
5794a9ae06 Bad copy pasta 2023-02-03 09:04:22 -06:00
Ben Meadors
835e6ab85e Missed RSSI 2023-02-03 08:52:32 -06:00
Ben Meadors
b97e61d8f8 Whoops 2023-02-03 08:51:02 -06:00
Ben Meadors
d9031610ab Connection status admin message 2023-02-03 08:50:10 -06:00
Ben Meadors
a8dd497575 Contain it 2023-02-02 14:40:18 -06:00
Ben Meadors
971ecd117c Whoooosh before my battery dies 2023-02-02 14:11:48 -06:00
Ben Meadors
e8e04d23d7 WIP 2023-02-02 14:05:58 -06:00
Thomas Göttgens
3c6bbff4f9 Adjust braces to match DeviceTelemetry
this is to force correct order of evaluation.
2023-02-02 19:37:28 +01:00
Thomas Göttgens
f6c6c2912f update enviro module to not create copies 2023-02-02 18:17:52 +01:00
Thomas Göttgens
a13adfb598 fixes #2239 2023-02-02 18:17:52 +01:00
Thomas Göttgens
8734afa7be Merge branch 'rsyslog-client' of github.com:meshtastic/firmware into rsyslog-client 2023-02-01 15:25:43 +01:00
Thomas Göttgens
5b75abc6f7 guard-clause use of syslog object 2023-02-01 15:25:25 +01:00
Thomas Göttgens
e4d455640f Merge branch 'master' into rsyslog-client 2023-02-01 15:09:44 +01:00
Thomas Göttgens
090d399843 hook up additional rsyslog output if debug printing is active 2023-02-01 15:09:07 +01:00
Thomas Göttgens
c908e61611 Update architecture.h
Add Namespace
2023-02-01 11:14:28 +01:00
Thomas Göttgens
3dda6e14f7 Trunk Fmt 2023-02-01 11:14:28 +01:00
Mark Trevor Birss
f0f819f403 Update architecture.h 2023-02-01 11:14:28 +01:00
Thomas Göttgens
39bb9f21ac trunk fmt 2023-01-31 18:36:20 +01:00
Thomas Göttgens
7750dd2d46 debug asserts 2023-01-31 18:36:20 +01:00
Thomas Göttgens
d34f6d0f68 the cake is a lie 2023-01-31 18:34:40 +01:00
Thomas Göttgens
d02588ad85 Merge pull request #2236 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2023-01-31 17:27:35 +01:00
thebentern
e4342d9715 [create-pull-request] automated change 2023-01-31 17:26:57 +01:00
Thomas Göttgens
1f0e64e794 Merge branch 'master' into rsyslog-client 2023-01-31 17:26:23 +01:00
Thomas Göttgens
e1914dd464 Fix build errors for other platforms 2023-01-31 17:25:18 +01:00
Thomas Göttgens
04add9b91e revert config changes accidentally pushed 2023-01-31 15:56:02 +01:00
Thomas Göttgens
5e1c39eb0f RP2040 toolchain updated 2023-01-31 15:51:21 +01:00
Thomas Göttgens
661894f9f9 fix nRF52 and linter errors. 2023-01-31 14:20:04 +01:00
Ben Meadors
5d1c06b72f Merge pull request #2233 from meshtastic/fix-localonly
Set encryptedOk to false for local_only rebroadcast
2023-01-30 15:06:07 -06:00
Ben Meadors
1407952410 Fmt 2023-01-30 14:50:57 -06:00
Ben Meadors
860aca9335 Set encryptedOk to false for local_only rebroadcast 2023-01-30 14:50:03 -06:00
Thomas Göttgens
104ffe36b2 Merge branch 'master' into rsyslog-client 2023-01-30 19:06:42 +01:00
Ben Meadors
5c22901ff1 Merge pull request #2232 from meshtastic/prefer-repeaters-too
Weight tx delay to prefer Repeaters as well
2023-01-30 11:55:43 -06:00
Ben Meadors
27bd4fa32e Merge branch 'master' into prefer-repeaters-too 2023-01-30 10:53:44 -06:00
Ben Meadors
2be805ce81 Merge pull request #2231 from meshtastic/bug-2205
Do not send when region unset
2023-01-30 10:53:31 -06:00
Ben Meadors
0a3e512387 Merge branch 'master' into prefer-repeaters-too 2023-01-30 10:29:14 -06:00
Ben Meadors
7b249deb26 Trunk it 2023-01-30 10:29:07 -06:00
Thomas Göttgens
7aa4e94e45 Do not send when region unset 2023-01-30 17:25:21 +01:00
Ben Meadors
dab2bb3bcc Weight tx delay to prefer Repeaters as well 2023-01-30 10:24:46 -06:00
Thomas Göttgens
afcd7acfab User configurable center frequency 2023-01-30 17:24:19 +01:00
caveman99
0188edb342 [create-pull-request] automated change 2023-01-30 15:57:15 +01:00
Ben Meadors
cd6d8e519b Merge pull request #2226 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2023-01-30 07:26:43 -06:00
thebentern
02f49d5347 [create-pull-request] automated change 2023-01-30 02:39:42 +00:00
Ben Meadors
2242b68d13 Merge pull request #2225 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2023-01-29 20:09:37 -06:00
thebentern
a6416f4f08 [create-pull-request] automated change 2023-01-30 02:07:54 +00:00
Ben Meadors
a1d8960f38 Merge pull request #2224 from meshtastic/rebroadcast-modes
Added modes for rebroadcast
2023-01-29 17:59:20 -06:00
Ben Meadors
b1656893ac Merge branch 'master' into rebroadcast-modes 2023-01-29 17:58:57 -06:00
Ben Meadors
8c0060ecd7 Peg to ref that has RX high gain persistance 2023-01-29 17:51:20 -06:00
Ben Meadors
0633b2f238 Verbiage 2023-01-29 17:45:24 -06:00
Ben Meadors
ec1358b050 Debug log for indicator 2023-01-29 15:42:40 -06:00
Ben Meadors
cd35e92471 Added modes for rebroadcast 2023-01-29 14:22:51 -06:00
Ben Meadors
76df5265cb Merge pull request #2223 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2023-01-29 13:58:36 -06:00
thebentern
5f7adf27c3 [create-pull-request] automated change 2023-01-29 19:57:41 +00:00
Thomas Göttgens
c3d08df18c Merge pull request #2198 from folkertvanheusden/timestamp-in-recv-msgs
show timestamp for received messages
2023-01-29 20:26:09 +01:00
Thomas Göttgens
0b84c7c0f3 trunk fmt 2023-01-29 19:42:36 +01:00
Thomas Göttgens
cf5485112b Merge branch 'master' into timestamp-in-recv-msgs 2023-01-29 19:25:41 +01:00
Ben Meadors
43096fb474 Merge pull request #2221 from GUVWAF/repeaterTraceroute 2023-01-29 11:47:43 -06:00
Ben Meadors
27b1428d6e Merge branch 'master' into repeaterTraceroute 2023-01-29 11:14:18 -06:00
Ben Meadors
915404dbe5 Merge pull request #2222 from meshtastic/endof-presets-love 2023-01-29 11:12:52 -06:00
Ben Meadors
ab6402e4f4 Merge branch 'master' into repeaterTraceroute 2023-01-29 10:11:58 -06:00
Ben Meadors
00196ab7e7 Long moderate 2023-01-29 09:53:38 -06:00
GUVWAF
14831e597c Add TraceRouteModule to Repeater 2023-01-29 16:37:02 +01:00
GUVWAF
c499302092 Remove decode guard clause for repeater 2023-01-29 16:32:18 +01:00
Ben Meadors
9c7a4aab9e Merge pull request #2220 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2023-01-29 07:57:45 -06:00
thebentern
7ed39d27e4 [create-pull-request] automated change 2023-01-29 13:57:30 +00:00
thebentern
0e6cfcd48a [create-pull-request] automated change 2023-01-29 11:04:38 +01:00
Ben Meadors
aafbde0f10 Remove the dirty d 2023-01-28 14:50:07 -06:00
Ben Meadors
f29beeb748 Merge pull request #2217 from meshtastic/tracker-role
Tracker role and role based defaults
2023-01-28 14:45:58 -06:00
Ben Meadors
75ea6fd704 Update interval 2023-01-28 14:44:47 -06:00
Ben Meadors
171c1df3fa Role based defaults 2023-01-28 14:32:57 -06:00
Ben Meadors
e05a007fc6 Merge pull request #2214 from meshtastic/repeater-role
Skip decoding packets for Repeaters
2023-01-28 13:49:12 -06:00
Ben Meadors
30a1810e12 Merge branch 'master' into repeater-role 2023-01-28 13:49:02 -06:00
Ben Meadors
bdf3fe3f5c Logging tweaks 2023-01-28 13:40:14 -06:00
Ben Meadors
d9af4f46fa Skip decoding for Repeaters 2023-01-28 13:28:57 -06:00
Ben Meadors
9d2fbec511 Merge pull request #2213 from meshtastic/repeater-role
Start of repeater role with in firmware
2023-01-28 11:44:28 -06:00
Ben Meadors
f45a25b358 Fmt 2023-01-28 09:18:06 -06:00
Ben Meadors
92a43685a8 Modules 2023-01-28 09:13:01 -06:00
Ben Meadors
103f1992dd Yank repeater module and just guard clause the alloc 2023-01-28 09:11:12 -06:00
Ben Meadors
e229a67d25 More friends 2023-01-28 08:44:29 -06:00
Ben Meadors
a7153a7aa9 Be a friend 2023-01-28 08:40:50 -06:00
Ben Meadors
14372c7e35 Fmt 2023-01-28 08:18:56 -06:00
Ben Meadors
a5f80167e0 Remove comments 2023-01-28 08:18:47 -06:00
Ben Meadors
654d38ed3f Router 2023-01-28 08:17:29 -06:00
Ben Meadors
e01e830c0e Print 2023-01-28 08:09:10 -06:00
Ben Meadors
db192481bd Swap out reliable router with flood router and dump modules 2023-01-28 08:03:32 -06:00
Ben Meadors
e8908784f9 Format 2023-01-28 06:39:14 -06:00
Ben Meadors
de82119415 Start of repeater role with in firmware 2023-01-28 06:38:13 -06:00
Ben Meadors
cda7e8b6a5 Merge pull request #2212 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2023-01-27 14:17:50 -06:00
thebentern
96f763dfa3 [create-pull-request] automated change 2023-01-27 20:16:23 +00:00
Ben Meadors
57b47cf1e1 Merge pull request #2211 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2023-01-27 12:27:22 -06:00
thebentern
7950739d85 [create-pull-request] automated change 2023-01-27 17:56:16 +00:00
Ben Meadors
2baaad8298 I swear 2023-01-27 11:19:45 -06:00
Ben Meadors
2e8832babb Trunk, you got a big storm coming, honey 2023-01-27 10:22:17 -06:00
Ben Meadors
ed155476ac Merge pull request #2210 from meshtastic/heap-reboot
move temporary reboot code to blink thread
2023-01-27 08:21:49 -06:00
Thomas Göttgens
61028293b8 move temporary reboot code to blink thread 2023-01-27 14:46:53 +01:00
Ben Meadors
708327240e Merge branch 'master' into timestamp-in-recv-msgs 2023-01-26 12:12:25 -06:00
Ben Meadors
d14bd652eb Merge pull request #2204 from meshtastic/rak-4631-fix
Potential fix for TX problem in RAK-4631 cores and other SX126X ant switch issues
2023-01-25 16:17:07 -06:00
Ben Meadors
cb3d5a5748 Comment about external PA module boards 2023-01-25 15:48:42 -06:00
Ben Meadors
d51aa60864 Missed one 2023-01-25 15:03:59 -06:00
Ben Meadors
9b18d5d85f Fmt 2023-01-25 14:59:12 -06:00
Ben Meadors
25096c5c63 Use radiolib native tx/rx_en switch control 2023-01-25 14:58:50 -06:00
Ben Meadors
f1fd41a378 Add to Eink target as well 2023-01-25 11:48:11 -06:00
folkert van heusden
65c0b8e33b Also print timestamp in bold 2023-01-25 17:41:54 +01:00
Ben Meadors
ca91447c0e For science! 2023-01-25 10:10:09 -06:00
Sacha Weatherstone
d876a5254e Merge branch 'master' into timestamp-in-recv-msgs 2023-01-25 10:06:04 +10:00
Ben Meadors
4a0f3f31cb Merge pull request #2201 from folkertvanheusden/xmodem-check
code reduction
2023-01-24 15:14:03 -06:00
folkert van heusden
f07963e802 Small tweak that reduces the number of lines of code in
XModemAdapter::check to 1. It should be functionally the same.
2023-01-24 21:30:16 +01:00
Thomas Göttgens
c7937e73a4 Merge branch 'master' into timestamp-in-recv-msgs 2023-01-24 20:47:35 +01:00
Ben Meadors
cb8532f2df Protos 2023-01-24 12:16:01 -06:00
Folkert van Heusden
747292e1e5 Merge branch 'master' into timestamp-in-recv-msgs 2023-01-24 18:57:34 +01:00
Ben Meadors
0b1e1687ae Merge pull request #2157 from andrew-moroz/sx126x-rx-boosted-gain
sx126x-rx-boosted-gain: add support for setting Rx gain mode on SX126x chipsets
2023-01-24 11:54:16 -06:00
folkert van heusden
91575e6241 When a message is received and displayed, include the
recevieve-timestamp. So now it functions as a clock and due to the 900s
default screen-lock-timeout you still have an idea of when the message
was received.
2023-01-24 18:52:09 +01:00
Ben Meadors
006cddd5cb Merge branch 'master' into sx126x-rx-boosted-gain 2023-01-24 10:04:31 -06:00
Ben Meadors
4d7e3329d9 Merge pull request #2185 from code8buster/gps-fixedposboot
GPS acquisiton on boot only
2023-01-24 10:04:06 -06:00
Ben Meadors
9e8342eb8f Merge branch 'master' into gps-fixedposboot 2023-01-24 10:01:53 -06:00
Thomas Göttgens
afb4d141dc remove double endif 2023-01-23 22:42:32 +01:00
Thomas Göttgens
19d864b5ce Also reboot if no heap debugging enabled 2023-01-23 22:42:32 +01:00
Thomas Göttgens
e8186f7dba how did that sneak in? 2023-01-23 21:57:41 +01:00
Thomas Göttgens
81854a173a fix #2109 json mqtt on secondary channel 2023-01-23 21:57:41 +01:00
Thomas Göttgens
083dcef9d6 don't define default pins for these. 2023-01-23 17:18:19 +01:00
Ben Meadors
5f0662d47d Merge branch 'master' into gps-fixedposboot 2023-01-23 06:35:53 -06:00
Ben Meadors
76022b65c6 Merge pull request #2192 from meshtastic/xmodem-fix
tryfix: also clear the second buffer.
2023-01-23 06:35:38 -06:00
Ben Meadors
2df81810ec Merge branch 'master' into sx126x-rx-boosted-gain 2023-01-23 06:06:22 -06:00
Thomas Göttgens
efa1445df4 Merge branch 'master' into gps-fixedposboot 2023-01-23 12:48:23 +01:00
code8buster
53d096b58e Disable the GPS thread after factory reset has been requested 2023-01-23 06:34:28 -05:00
Thomas Göttgens
4da1fb8e27 there's a special place in hell for include paths... 2023-01-23 06:34:10 -05:00
Thomas Göttgens
8e0dcb09e8 tempfix: reboot ESP Node if heap runs low.
fixes #2165
2023-01-23 06:34:10 -05:00
Thomas Göttgens
014946ad0e tryfix: also clear the second buffer.
Todo: do we really need 2 buffers here?
2023-01-23 12:29:10 +01:00
Thomas Göttgens
3aebb1ffb3 there's a special place in hell for include paths... 2023-01-23 12:27:16 +01:00
Thomas Göttgens
3b80421403 tempfix: reboot ESP Node if heap runs low.
fixes #2165
2023-01-23 12:27:16 +01:00
Thomas Göttgens
255d433ebf Merge branch 'master' into gps-fixedposboot 2023-01-23 11:16:19 +01:00
Ben Meadors
2c1b7840c5 Make this pr great again 2023-01-23 09:22:40 +01:00
Thomas Göttgens
e9acf413fb After thoroughly reading schematics and documentation, i conclude that this is theoretically the right definition for this hookup. 2023-01-23 09:22:40 +01:00
Ben Meadors
7c60896072 Merge branch 'master' into gps-fixedposboot 2023-01-22 20:55:49 -06:00
Ben Meadors
1941d196bb Additional docker tags 2023-01-22 13:52:01 -06:00
Thomas Göttgens
3120744716 Missed one :-) 2023-01-22 18:58:14 +01:00
Ben Meadors
2ecf273cf3 Merge pull request #2189 from meshtastic/xmodem-fix-2
Xmodem fix 2
2023-01-22 09:12:51 -06:00
Ben Meadors
50cee4a6c8 Oops! 2023-01-22 08:51:30 -06:00
Ben Meadors
ac6d4e33d4 Format 2023-01-22 08:49:06 -06:00
Ben Meadors
4c9f0b2646 Just start a new PR. Conflicts were too wild 2023-01-22 08:48:31 -06:00
Ben Meadors
fab663d1b7 Merge branch 'master' into gps-fixedposboot 2023-01-21 20:34:41 -06:00
Ben Meadors
fc5e80a5cc Merge pull request #2172 from meshtastic/stm32wl-wip
Stm32wl wip
2023-01-21 20:29:36 -06:00
Ben Meadors
266c61065d I swear I did this before you butthole 2023-01-21 19:51:24 -06:00
Ben Meadors
e2e7658789 w/e 2023-01-21 19:24:33 -06:00
Thomas Göttgens
a421edce49 Merge branch 'master' into stm32wl-wip 2023-01-21 21:55:09 +01:00
Ben Meadors
3f3a4ce44c Merge pull request #2187 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2023-01-21 14:49:56 -06:00
caveman99
8aab63dace [create-pull-request] automated change 2023-01-21 20:37:04 +00:00
Thomas Göttgens
aac9b5db30 and the saga continues 2023-01-21 21:23:24 +01:00
Thomas Göttgens
6f30a84afc dayum! 2023-01-21 21:23:24 +01:00
Thomas Göttgens
c53c87499b missed a few 2023-01-21 21:23:24 +01:00
Thomas Göttgens
cdf379616c whatever makes trunk happy. 2023-01-21 21:23:24 +01:00
Thomas Göttgens
6fdb93cd16 re-add namespacing in protobufs. Let's see what i missed. Portduino likely ...
Checking in generated on purpose.
2023-01-21 21:23:24 +01:00
Thomas Göttgens
ab3446faed Back out changes to non-source files 2023-01-21 21:23:24 +01:00
Thomas Göttgens
9ebe24e680 that didn't hurt at all 2023-01-21 21:23:24 +01:00
Thomas Göttgens
811ac15a81 even those were formatted. 2023-01-21 21:23:24 +01:00
Thomas Göttgens
51b2c431d9 trunk roundhouse kick 2023-01-21 21:23:24 +01:00
Thomas Göttgens
6cf18b7d07 trunk recommended this change ¯\_(ツ)_/¯ 2023-01-21 21:23:24 +01:00
code8buster
52e8dc7317 just do sleep through the observer like I have been 2023-01-21 08:33:43 -05:00
GUVWAF
d8e644191b Merge pull request #2184 from GUVWAF/trunk
Make Trunk happy
2023-01-21 13:27:30 +01:00
code8buster
fdc47728af Put GPS thread to sleep post factory reset request 2023-01-21 07:21:23 -05:00
code8buster
54b4b67e5c add logic for GPS single acquisition on bootup fixed-position 2023-01-21 07:21:23 -05:00
GUVWAF
bcf24b8187 Make Trunk happy 2023-01-21 13:01:19 +01:00
GUVWAF
c628c70db2 Merge pull request #2179 from nukevoid/master
Fix vulnerability with "h.from == 0"
2023-01-21 12:37:50 +01:00
Nukevoid
7f9e638140 Merge branch 'master' into master 2023-01-21 02:18:33 +02:00
a_filonichev
5a2ad03294 Merge branch 'master' of https://github.com/nukevoid/firmware 2023-01-20 23:41:23 +02:00
a_filonichev
a584cac827 fix rxGood counter 2023-01-20 23:41:05 +02:00
Thomas Göttgens
8f5338dc85 Merge pull request #2174 from meshtastic/SH1107
Sh1107 support (128x128)
2023-01-20 22:15:02 +01:00
Thomas Göttgens
8c434c7084 Merge branch 'SH1107' of github.com:meshtastic/firmware into SH1107 2023-01-20 21:54:03 +01:00
Thomas Göttgens
88c84dd806 trunk again 2023-01-20 21:53:34 +01:00
Ben Meadors
f9f083da51 Merge branch 'master' into SH1107 2023-01-20 14:44:19 -06:00
Nukevoid
481880872c Merge branch 'master' into master 2023-01-20 19:03:37 +02:00
Thomas Göttgens
0eaf0747f4 fix building other screen adapters 2023-01-20 16:34:39 +01:00
Ben Meadors
9a7121d8c9 Merge pull request #2175 from GUVWAF/printFixes
Fix two print format specifiers
2023-01-20 09:26:39 -06:00
Thomas Göttgens
cbd6a0065b trunk format 2023-01-20 15:04:09 +01:00
Thomas Göttgens
50f72b0ea0 add the possibility to #define USE_SH1107 to fix boards to this display. 2023-01-20 15:04:09 +01:00
Thomas Göttgens
74ec5e8a5c add support for 128x128 b/w display GME128128-01-IIC 2023-01-20 15:04:09 +01:00
Thomas Göttgens
bec0cda175 Merge branch 'master' into printFixes 2023-01-20 14:32:03 +01:00
Ben Meadors
ca298d8a7d Merge branch 'master' into sx126x-rx-boosted-gain 2023-01-20 07:08:53 -06:00
a_filonichev
3eaa054c68 Fix vulnerability with "h.from == 0"
// altered packed with "from == 0" can do Remote Node Administration without permission
2023-01-20 01:38:13 +02:00
Thomas Göttgens
48ea836a5c Merge pull request #2177 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2023-01-19 15:46:06 +01:00
caveman99
fda1e29c4d [create-pull-request] automated change 2023-01-19 14:14:12 +00:00
GUVWAF
836559cda1 Fix two print format specifiers 2023-01-19 15:01:44 +01:00
Thomas Göttgens
c04980084a Fix line endings at LF and make windows proto generation work again. needs cygwin64 in path 2023-01-19 14:04:31 +01:00
Thomas Göttgens
111ec56028 Merge pull request #2173 from meshtastic/triple-double
Double click sends ad-hoc position, triple turns off gps
2023-01-19 08:20:53 +01:00
Ben Meadors
384eac9a87 Format plz 2023-01-18 21:13:31 -06:00
Ben Meadors
6a5e0edb60 Double click sends ad-hoc position, triple turns off gps 2023-01-18 21:02:45 -06:00
Ben Meadors
9d47f7a531 Format 2023-01-18 20:03:10 -06:00
Ben Meadors
660a73d58c Stuff 2023-01-18 19:45:39 -06:00
Ben Meadors
412fbea978 WIP 2023-01-18 19:24:18 -06:00
Ben Meadors
293625924d Merge branch 'master' into sx126x-rx-boosted-gain 2023-01-18 16:57:41 -06:00
Ben Meadors
8984989412 Merge branch 'master' into rsyslog-client 2023-01-18 16:56:24 -06:00
Ben Meadors
4cfedc4b57 Kill it and grill it 2023-01-18 16:34:21 -06:00
Ben Meadors
cd57df3f4f Update main_matrix.yml 2023-01-18 16:18:01 -06:00
Ben Meadors
db729eb707 Merge branch 'master' into rsyslog-client 2023-01-18 16:15:03 -06:00
Ben Meadors
6c41960919 Remove simulator for now 2023-01-18 15:55:58 -06:00
Ben Meadors
ff029ad752 Formatting 2023-01-18 15:37:23 -06:00
Ben Meadors
202223236d Merge branch 'master' into rsyslog-client 2023-01-18 15:17:03 -06:00
Ben Meadors
48609b5bdd Merge pull request #2170 from meshtastic/device-metadata-enhanced
Add role and position flags to metadata
2023-01-18 15:16:40 -06:00
Ben Meadors
dad8e2bf6a Merge branch 'master' into device-metadata-enhanced 2023-01-18 15:16:20 -06:00
Ben Meadors
9cda2e9058 Add role and position flags to metadata 2023-01-18 15:15:02 -06:00
Thomas Göttgens
fdf7c3a812 Merge branch 'master' into rsyslog-client 2023-01-18 22:13:38 +01:00
Ben Meadors
72dad37138 Merge pull request #2169 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2023-01-18 15:12:44 -06:00
thebentern
ee25a488ef [create-pull-request] automated change 2023-01-18 21:12:03 +00:00
Ben Meadors
9046dacec8 I don't like this formatting but I need trunk to STFU 2023-01-18 14:51:48 -06:00
Thomas Göttgens
f86eef66c8 Simple UDP calls, if wired up a fair bit of this can go again.
this is preliminary work
2023-01-18 21:35:51 +01:00
Ben Meadors
b218ea9ec7 Hopefully ignore generated files 2023-01-18 11:04:06 -06:00
Ben Meadors
6f70d39bae Merge pull request #2166 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2023-01-18 10:22:33 -06:00
thebentern
80f259cc6c [create-pull-request] automated change 2023-01-18 16:19:47 +00:00
Ben Meadors
36b3bf2211 Strip namspace prefix 2023-01-18 10:16:15 -06:00
Ben Meadors
92525587e1 Merge pull request #2164 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2023-01-18 09:00:17 -06:00
thebentern
5189e328b6 [create-pull-request] automated change 2023-01-18 14:57:44 +00:00
Ben Meadors
4d4af7de59 generated paths experiment 2023-01-18 08:56:47 -06:00
Ben Meadors
1b932c6bbe Fix scripts patch and remove files in previous dir 2023-01-18 07:53:19 -06:00
Ben Meadors
4065fb1709 Merge pull request #2162 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2023-01-18 07:43:35 -06:00
thebentern
cf39628222 [create-pull-request] automated change 2023-01-18 13:42:53 +00:00
Ben Meadors
d7fa8fea8d Update protos path for generator scripts 2023-01-18 07:39:05 -06:00
Sacha Weatherstone
db3d66544d Setup Trunk (#2143)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-01-17 17:35:26 +11:00
Andrew Moroz
0a2539650e sx126x-rx-boosted-gain: add support for setting Rx gain mode on SX126x chipsets 2023-01-17 00:56:15 -05:00
Thomas Göttgens
d35b619063 Merge pull request #2112 from meshtastic/xmodem-proto
Add Chunked File Transfer to API
2023-01-16 20:36:09 +01:00
Thomas Göttgens
0e51a42ce2 Merge branch 'master' into xmodem-proto 2023-01-16 20:11:02 +01:00
Ben Meadors
d5f7d741c3 Merge pull request #2153 from meshtastic/develop
Develop to master
2023-01-16 13:00:15 -06:00
Ben Meadors
cc0cccbd1b Coerce int 2023-01-16 12:26:10 -06:00
Ben Meadors
6c388e0da8 Merge branch 'master' into develop 2023-01-16 11:10:08 -06:00
Thomas Göttgens
9f3c09cf40 adapt to new proto names 2023-01-16 18:09:17 +01:00
Ben Meadors
34b2d51113 Patch locked_to 2023-01-16 11:05:36 -06:00
Thomas Göttgens
1dbd0f8dd1 Merge branch 'develop' of github.com:meshtastic/firmware into develop 2023-01-16 17:56:57 +01:00
Thomas Göttgens
0f4306158c fix S&F Problem 2023-01-16 17:56:48 +01:00
Thomas Göttgens
d5a3acb83a Trigger rebuild 2023-01-16 17:55:17 +01:00
Krezalis
efbdb273c3 Update RadioInterface.cpp 2023-01-16 17:55:17 +01:00
Krezalis
011013ab1a Update RadioInterface.cpp 2023-01-16 17:55:17 +01:00
Krezalis
49279e56d0 Update RadioInterface.cpp 2023-01-16 17:55:17 +01:00
Krezalis
1cfda77356 Add 868 MHz Ukrainian Band 2023-01-16 17:55:17 +01:00
caveman99
f4779bd93f [create-pull-request] automated change 2023-01-16 17:51:45 +01:00
garthvh
e95db927ac [create-pull-request] automated change 2023-01-16 14:54:50 +01:00
Ben Meadors
a4d3fa55db Remove HAS_GPS for WSLv3 2023-01-16 14:54:50 +01:00
Thomas Göttgens
59ee0fb012 put legacy S&F call back in, till Apps support it. 2023-01-16 14:53:27 +01:00
Thomas Göttgens
5831124f1d Store and Forward: don't try to store a message if PSRAM is not initialized! 2023-01-16 14:53:27 +01:00
Thomas Göttgens
2b9f01f0e4 fix cppcheck 2023-01-16 11:08:48 +01:00
Thomas Göttgens
aca1241a7f Having a first stab at flawfinder errors 2023-01-16 10:55:40 +01:00
Thomas Göttgens
da0440ba17 Merge pull request #2145 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2023-01-15 21:21:38 +01:00
garthvh
85dd606423 [create-pull-request] automated change 2023-01-15 16:52:29 +00:00
Ben Meadors
7e27729dae Remove HAS_GPS for WSLv3 2023-01-15 08:24:20 -06:00
Ben Meadors
d49f19a67c Merge pull request #2137 from meshtastic/cherrypick-serialfix
re-merge fixes by @lesykm
2023-01-12 12:16:53 -06:00
Ben Meadors
5520d68b34 Merge pull request #2136 from meshtastic/serial-fix
re-merge fixes by @lesykm
2023-01-12 12:16:40 -06:00
Thomas Göttgens
c33569f833 re-merge fixes by @lesykm 2023-01-12 12:15:12 -06:00
Thomas Göttgens
8db3f317ab re-merge fixes by @lesykm 2023-01-12 19:08:41 +01:00
Ben Meadors
a3636ae8a1 Merge pull request #2133 from meshtastic/master
Master downstream merge
2023-01-12 10:22:56 -06:00
Ben Meadors
7936c7c8ae Remove the D! 2023-01-12 10:07:17 -06:00
Ben Meadors
2f3f19fda7 Merge pull request #2132 from meshtastic/develop
Remove DEBUG_HEAP flag from esp32 pio config on release
2023-01-12 09:37:33 -06:00
Ben Meadors
c89ca50cc4 Remove DEBUG_HEAP flag from esp32 pio config on release 2023-01-12 09:33:55 -06:00
Thomas Göttgens
867e55b9e7 sync mqtt with develop 2023-01-12 16:09:03 +01:00
Ben Meadors
28b1616630 Merge pull request #2131 from meshtastic/develop
Develop to master for 2.0.13 release candidate
2023-01-12 08:37:11 -06:00
Thomas Göttgens
42122f3d0f Merge branch 'master' into develop 2023-01-12 15:01:56 +01:00
Ben Meadors
f905763161 Merge pull request #2129 from meshtastic/nice-duty-cycle
Chance calculation for Nice TX. Still same value but dynamically based on duty cycle.
2023-01-12 07:20:29 -06:00
Thomas Göttgens
bd2b766a36 Rename to make function clearer 2023-01-12 14:03:06 +01:00
Thomas Göttgens
bd51cbd721 Chance calculation for Nice TX. Still same value but dynamically based on duty cycle. 2023-01-12 09:15:54 +00:00
Thomas Göttgens
5e66dd0dad File Transfer: add debug logging and allocate memory used. 2023-01-12 10:00:52 +01:00
Thomas Göttgens
80d1a993dd Merge branch 'develop' of github.com:meshtastic/firmware into xmodem-proto 2023-01-12 10:00:04 +01:00
Ben Meadors
e3fd17772d Merge pull request #2127 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2023-01-11 19:40:51 -06:00
thebentern
440b965e71 [create-pull-request] automated change 2023-01-12 01:38:21 +00:00
Ben Meadors
cf0fb13a12 Merge pull request #2126 from GUVWAF/TxAirLim
Don't send NodeInfo and DeviceTelemetry at high Tx air utilization
2023-01-11 19:26:40 -06:00
GUVWAF
c0166773e8 Portduino can handle this 2023-01-11 21:53:23 +01:00
GUVWAF
fc775012ea Don't send NodeInfo and DeviceTelemetry at high Tx air util
Also move airtime checking to airtime class
2023-01-11 21:52:19 +01:00
Ben Meadors
d7a71e46aa Merge pull request #2125 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2023-01-11 14:36:10 -06:00
thebentern
721f87af7e [create-pull-request] automated change 2023-01-11 20:35:13 +00:00
Ben Meadors
a354cebd88 Update protos ref 2023-01-11 14:28:10 -06:00
Ben Meadors
97680ca730 Merge pull request #2123 from meshtastic/time
Allow time from phone to be sent to the mesh
2023-01-11 09:11:45 -06:00
Ben Meadors
17a2589b35 Allow time from phone to be sent to the mesh 2023-01-11 07:50:07 -06:00
Thomas Göttgens
4f71ab07c9 2.0.12 is out already. Bump develop too. 2023-01-11 14:33:54 +01:00
Ben Meadors
1f6a8eae86 Merge pull request #2121 from GUVWAF/NAKtoAPI
Send NAK to API only upon duty cycle limit
2023-01-10 14:20:51 -06:00
GUVWAF
ab9d0ba543 Report actual RoutingError 2023-01-10 21:12:40 +01:00
GUVWAF
e13fb9919e Send NAK only to the API upon duty cycle limit 2023-01-10 21:12:17 +01:00
GUVWAF
a3b93a4dcf Better not to compare float directly 2023-01-10 21:10:09 +01:00
Thomas Göttgens
6b0f18e1e4 Merge pull request #2113 from meshtastic/mqtt-fix
Find the downlink channel to post packet to.
2023-01-10 20:49:18 +01:00
Thomas Göttgens
312ef790fc Merge pull request #2119 from meshtastic/rak-shutdown-rail
Turn of 3.3v rail on RAK-4631 on shutdown
2023-01-10 19:03:03 +01:00
Ben Meadors
713f7d5996 Turn of 3.3v rail on RAK-4631 on shutdown 2023-01-10 07:36:19 -06:00
Ben Meadors
3985008e06 Merge pull request #2116 from meshtastic/rak4631-radiofix 2023-01-09 22:13:46 -06:00
Thomas Göttgens
8f2155f8f9 Merge branch 'develop' into mqtt-fix 2023-01-09 23:28:08 +01:00
Thomas Göttgens
1fc5d70221 let the library handle the reconnect, manually do it after 5 seconds 2023-01-09 23:26:47 +01:00
Ben Meadors
e7d425ef6e Until we figure out what's going on 2023-01-09 16:19:42 -06:00
Thomas Göttgens
c63536d948 switch to 16 bit packet number 2023-01-09 20:23:32 +01:00
Thomas Göttgens
9c1cfe9358 Merge pull request #2114 from meshtastic/refactor-apiserver
make a template class for API Server
2023-01-09 20:11:01 +01:00
Thomas Göttgens
971565aed3 Merge branch 'develop' into xmodem-proto 2023-01-09 20:08:37 +01:00
Thomas Göttgens
3a6e3464e6 notify phoneAPI about new packages to process 2023-01-09 20:06:11 +01:00
Thomas Göttgens
0181e186ac Merge pull request #2106 from meshtastic/assert-cleanup
initial cleanup work
2023-01-09 19:45:23 +01:00
Thomas Göttgens
86748bf88e fix building portduino and make cppcheck happy 2023-01-09 19:23:41 +01:00
Thomas Göttgens
5fd00b2538 - make a template class for API Server
- Skip a lot of duplicate code
- add a hexDump output - might come in handy
- refactor directory names
- remove unused debugOut that was generating template errors
2023-01-09 17:03:52 +01:00
Thomas Göttgens
5cec370cf5 getByName was not used anywhere in the code so that change is safe.
Please TEST this as i don't have a working Json setup in mqtt at the moment.
2023-01-09 11:28:21 +01:00
Thomas Göttgens
fce52e16e3 update license. This is only loosely based on Xmodem. 2023-01-08 18:34:56 +01:00
Thomas Göttgens
0e7797f3bb Adding to generated for now, protobuf PR will come when it works ... :-) 2023-01-08 18:15:51 +01:00
Thomas Göttgens
81ee6dd799 first crash from stress test 2023-01-07 23:40:47 +01:00
Thomas Göttgens
49172e416e Merge pull request #2108 from markbirss/develop
Add initial support for BETAFPV ELRS Micro TX Module 2.4G with ESP32 CPU
2023-01-07 22:50:04 +01:00
Ben Meadors
57f185c26b Merge pull request #2104 from meshtastic/hydra-gps
Hydra gps troubleshooting
2023-01-07 14:51:46 -06:00
Thomas Göttgens
3a8ffe7ac2 ah feck 2023-01-07 15:43:17 +01:00
Thomas Göttgens
d8b85f9a09 fingers crossed 2023-01-07 15:24:46 +01:00
Mark Trevor Birss
4d7402839e Update platformio.ini 2023-01-07 16:00:27 +02:00
Thomas Göttgens
8465467aa8 2nd batch 2023-01-07 14:57:00 +01:00
Thomas Göttgens
2a0b8093ea freakin' nitpickin' cpp_check 2023-01-07 13:59:40 +01:00
Thomas Göttgens
96fa5dafb8 fixing portduino 2023-01-07 13:36:02 +01:00
Thomas Göttgens
be2d3f7769 fix leak 2023-01-07 13:28:36 +01:00
Thomas Göttgens
b283e526bf fix for nRF52 and Portduino 2023-01-07 13:25:29 +01:00
Thomas Göttgens
03c5dfc7a8 initial cleanup work 2023-01-07 13:16:58 +01:00
Mark Trevor Birss
52cfd62031 Update SX128xInterface.cpp 2023-01-07 14:05:16 +02:00
Mark Trevor Birss
c98dc4cae0 Update variant.h 2023-01-07 13:48:35 +02:00
Mark Trevor Birss
f21212dd3e Update platformio.ini 2023-01-07 13:23:33 +02:00
Mark Trevor Birss
0e0ccad489 Update variant.h 2023-01-07 13:22:32 +02:00
Mark Trevor Birss
9f1c77da76 Create variant.h 2023-01-07 13:01:14 +02:00
Mark Trevor Birss
7c1c49b8ab Create platformio.ini 2023-01-07 13:00:50 +02:00
Ben Meadors
f4099261df Hydra gps troubleshooting 2023-01-06 15:04:11 -06:00
Thomas Göttgens
450e7362f6 Merge pull request #2103 from kn6plv/fix-multicast-macaddress
Make sure we dont use a multicast MAC for ethernet
2023-01-06 12:43:48 +01:00
Tim Wilkinson
0b9c8e62ea Make sure we dont use a multicast MAC for ethernet 2023-01-05 22:31:57 -08:00
Ben Meadors
09efbb75b1 Merge pull request #2099 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2023-01-04 11:22:59 -06:00
thebentern
e5d9f1f946 [create-pull-request] automated change 2023-01-04 16:13:43 +00:00
Thomas Göttgens
988d5af69b Merge pull request #2097 from meshtastic/hotfix-01
External Notification Hotfix
2023-01-04 15:31:02 +01:00
Thomas Göttgens
9740f0a505 External Notification Hotfix 2023-01-04 14:45:28 +01:00
Thomas Göttgens
b64a74c0c5 add heap debugging back in too 2023-01-04 14:43:23 +01:00
Thomas Göttgens
d9f0dc7ea4 add MQTT outqueue back in (still broken) 2023-01-04 14:41:58 +01:00
pavelb-techspark
30ae4c2a38 Add QueueStatus sending to the firmware (#1820)
* Yank mqtt service envelope queue

* trybuildfix mqtt system

* removed too much

* no excessive heap debugging on release builds

* send QueueStatus messages

The QueueStatus message is sent as a response to the attempt to queue
an outgoing MeshPacket and contains statuses of the last queue
attempt, TX Queue space and capacity and MeshPacket.id that was
queued.

When TX Queue changes status from completely full to at least
a single slot free a QueueStatus message is also sent to notify
that user can queue more messages.

Signed-off-by: Pavel Boldin <pavel.b@techspark.engineering>

* WIP: update protobufs

Signed-off-by: Pavel Boldin <pavel.b@techspark.engineering>

* update protobufs

* regen protos

Signed-off-by: Pavel Boldin <pavel.b@techspark.engineering>
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
Co-authored-by: Sacha Weatherstone <sachaw100@hotmail.com>
2023-01-04 23:56:52 +11:00
Thomas Göttgens
d077be1496 add a possibility to flush the serial TX buffer on the console. 2023-01-04 10:37:27 +01:00
Thomas Göttgens
4f26a2a74a Update Unishox to latest V2 code, change is only cosmetic 2023-01-04 10:35:52 +01:00
thebentern
41f9636ba3 [create-pull-request] automated change 2023-01-04 10:35:07 +01:00
415 changed files with 13759 additions and 11495 deletions

4
.gitattributes vendored Normal file
View File

@@ -0,0 +1,4 @@
* text=auto eol=lf
*.{cmd,[cC][mM][dD]} text eol=crlf
*.{bat,[bB][aA][tT]} text eol=crlf
*.{sh,[sS][hH]} text eol=lf

View File

@@ -28,7 +28,7 @@ body:
description: What LoRa IC does the board have?
validations:
required: true
- type: input
id: link
attributes:

View File

@@ -1,5 +1,5 @@
name: 'Setup Build Base Composite Action'
description: 'Base build actions for Meshtastic Platform IO steps'
name: "Setup Build Base Composite Action"
description: "Base build actions for Meshtastic Platform IO steps"
runs:
using: "composite"
@@ -10,7 +10,7 @@ runs:
submodules: "recursive"
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Install cppcheck
shell: bash
run: |
@@ -38,4 +38,4 @@ runs:
- name: Upgrade platformio
shell: bash
run: |
pio upgrade
pio upgrade

View File

@@ -7,7 +7,7 @@ on:
required: true
type: string
jobs:
jobs:
build-esp32:
runs-on: ubuntu-latest
steps:
@@ -29,6 +29,13 @@ jobs:
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
- name: Build ESP32
run: bin/build-esp32.sh ${{ inputs.board }}
@@ -39,7 +46,7 @@ jobs:
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

View File

@@ -7,7 +7,7 @@ on:
required: true
type: string
jobs:
jobs:
build-nrf52:
runs-on: ubuntu-latest
steps:
@@ -30,4 +30,4 @@ jobs:
path: |
release/*.uf2
release/*.elf
release/*.zip
release/*.zip

View File

@@ -7,7 +7,7 @@ on:
required: true
type: string
jobs:
jobs:
build-rpi2040:
runs-on: ubuntu-latest
steps:
@@ -29,4 +29,4 @@ jobs:
name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip
path: |
release/*.uf2
release/*.elf
release/*.elf

View File

@@ -33,7 +33,7 @@ jobs:
- board: m5stack-coreink
- board: tbeam-s3-core
- board: tlora-t3s3-v1
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
@@ -41,6 +41,9 @@ jobs:
id: base
uses: ./.github/actions/setup-base
- name: Trunk Check
uses: trunk-io/trunk-action@v1
- name: Check ${{ matrix.board }}
run: bin/check-all.sh ${{ matrix.board }}
@@ -70,6 +73,7 @@ jobs:
- board: m5stack-coreink
- board: tbeam-s3-core
- board: tlora-t3s3-v1
- board: nano-g1-explorer
uses: ./.github/workflows/build_esp32.yml
with:
board: ${{ matrix.board }}
@@ -89,16 +93,16 @@ jobs:
with:
board: ${{ matrix.board }}
build-rpi2040:
strategy:
fail-fast: false
max-parallel: 2
matrix:
include:
- board: pico
uses: ./.github/workflows/build_rpi2040.yml
with:
board: ${{ matrix.board }}
# build-rpi2040:
# strategy:
# fail-fast: false
# max-parallel: 2
# matrix:
# include:
# - board: pico
# uses: ./.github/workflows/build_rpi2040.yml
# with:
# board: ${{ matrix.board }}
build-native:
runs-on: ubuntu-latest
@@ -109,14 +113,14 @@ jobs:
uses: ./.github/actions/setup-base
# We now run integration test before other build steps (to quickly see runtime failures)
- name: Build for native
run: platformio run -e native
- name: Integration test
run: |
.pio/build/native/program &
sleep 20 # 5 seconds was not enough
echo "Simulator started, launching python test..."
python3 -c 'from meshtastic.test import testSimulator; testSimulator()'
#- name: Build for native
# run: platformio run -e native
#- name: Integration test
# run: |
#.pio/build/native/program
#& sleep 20 # 5 seconds was not enough
#echo "Simulator started, launching python test..."
#python3 -c 'from meshtastic.test import testSimulator; testSimulator()'
- name: Build Native
run: bin/build-native.sh
@@ -132,27 +136,34 @@ jobs:
path: |
release/device-*.sh
release/device-*.bat
- name: Docker login
if: ${{ github.event_name == 'workflow_dispatch' }}
uses: docker/login-action@v2
with:
with:
username: meshtastic
password: ${{ secrets.DOCKER_TOKEN }}
- name: Docker setup
if: ${{ github.event_name == 'workflow_dispatch' }}
uses: docker/setup-buildx-action@v2
- name: Docker build and push
- name: Docker build and push tagged versions
if: ${{ github.event_name == 'workflow_dispatch' }}
uses: docker/build-push-action@v3
with:
context: .
file: ./Dockerfile
push: true
tags: meshtastic/device-simulator:${{ steps.version.outputs.version }}
- name: Docker build and push
if: github.ref == 'refs/heads/master'
uses: docker/build-push-action@v3
with:
context: .
file: ./Dockerfile
push: true
tags: meshtastic/device-simulator:latest
after-checks:
runs-on: ubuntu-latest
needs: [check]
@@ -165,7 +176,7 @@ jobs:
gather-artifacts:
runs-on: ubuntu-latest
needs: [build-esp32, build-nrf52, build-native, build-rpi2040]
needs: [build-esp32, build-nrf52, build-native] #, build-rpi2040]
steps:
- name: Checkout code
uses: actions/checkout@v3

19
.github/workflows/nightly.yml vendored Normal file
View File

@@ -0,0 +1,19 @@
name: Nightly
on:
schedule:
- cron: 0 8 * * 1-5
workflow_dispatch: {}
jobs:
trunk_check:
name: Trunk Check Upload
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Trunk Check
uses: trunk-io/trunk-action@v1
with:
trunk-token: ${{ secrets.TRUNK_TOKEN }}

View File

@@ -10,31 +10,31 @@ on:
jobs:
flawfinder:
runs-on: ubuntu-latest
name: Flawfinder
runs-on: ubuntu-latest
name: Flawfinder
steps:
# step 1
- name: clone application source code
uses: actions/checkout@v3
steps:
# step 1
- name: clone application source code
uses: actions/checkout@v3
# step 2
- name: flawfinder_scan
uses: david-a-wheeler/flawfinder@2.0.19
with:
arguments: '--sarif ./'
output: 'flawfinder_report.sarif'
# step 2
- name: flawfinder_scan
uses: david-a-wheeler/flawfinder@2.0.19
with:
arguments: "--sarif ./"
output: "flawfinder_report.sarif"
# step 3
- name: save report as pipeline artifact
uses: actions/upload-artifact@v3
with:
name: flawfinder_report.sarif
path: flawfinder_report.sarif
# step 3
- name: save report as pipeline artifact
uses: actions/upload-artifact@v3
with:
name: flawfinder_report.sarif
path: flawfinder_report.sarif
# step 4
- name: publish code scanning alerts
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: flawfinder_report.sarif
category: flawfinder
# step 4
- name: publish code scanning alerts
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: flawfinder_report.sarif
category: flawfinder

View File

@@ -6,39 +6,37 @@ on:
branches:
- master
schedule:
- cron: '0 1 * * 6'
- cron: "0 1 * * 6"
jobs:
semgrep-full:
runs-on: ubuntu-latest
container:
image: returntocorp/semgrep
runs-on: ubuntu-latest
container:
image: returntocorp/semgrep
steps:
steps:
# step 1
- name: clone application source code
uses: actions/checkout@v3
# step 1
- name: clone application source code
uses: actions/checkout@v3
# step 2
- name: full scan
run: |
semgrep \
--sarif --output report.sarif \
--metrics=off \
--config="p/default"
# step 2
- name: full scan
run: |
semgrep \
--sarif --output report.sarif \
--metrics=off \
--config="p/default"
# step 3
- name: save report as pipeline artifact
uses: actions/upload-artifact@v3
with:
name: report.sarif
path: report.sarif
# step 3
- name: save report as pipeline artifact
uses: actions/upload-artifact@v3
with:
name: report.sarif
path: report.sarif
# step 4
- name: publish code scanning alerts
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: report.sarif
category: semgrep
# step 4
- name: publish code scanning alerts
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: report.sarif
category: semgrep

View File

@@ -1,17 +1,14 @@
---
name: Semgrep Differential Scan
on:
pull_request
on: pull_request
jobs:
semgrep-diff:
runs-on: ubuntu-latest
container:
image: returntocorp/semgrep
steps:
# step 1
- name: clone application source code
uses: actions/checkout@v3

7
.trunk/.gitignore vendored Normal file
View File

@@ -0,0 +1,7 @@
*out
*logs
*actions
*notifications
plugins
user_trunk.yaml
user.yaml

View File

@@ -0,0 +1,4 @@
# Following source doesn't work in most setups
ignored:
- SC1090
- SC1091

View File

@@ -0,0 +1,10 @@
# Autoformatter friendly markdownlint config (all formatting rules disabled)
default: true
blank_lines: false
bullet: false
html: false
indentation: false
line_length: false
spaces: false
url: false
whitespace: false

View File

@@ -0,0 +1,7 @@
enable=all
source-path=SCRIPTDIR
disable=SC2154
# If you're having issues with shellcheck following source, disable the errors via:
# disable=SC1090
# disable=SC1091

View File

@@ -0,0 +1,14 @@
module.exports = {
plugins: [
{
name: "preset-default",
params: {
overrides: {
removeViewBox: false, // https://github.com/svg/svgo/issues/1128
sortAttrs: true,
removeOffCanvasPaths: true,
},
},
},
],
};

33
.trunk/trunk.yaml Normal file
View File

@@ -0,0 +1,33 @@
version: 0.1
cli:
version: 1.3.1
plugins:
sources:
- id: trunk
ref: v0.0.8
uri: https://github.com/trunk-io/plugins
lint:
enabled:
- git-diff-check
- gitleaks@8.15.2
- clang-format@14.0.0
- prettier@2.8.3
disabled:
- shellcheck@0.9.0
- shfmt@3.5.0
- oxipng@8.0.0
- actionlint@1.6.22
- markdownlint@0.33.0
- hadolint@2.12.0
- svgo@3.0.2
runtimes:
enabled:
- go@1.18.3
- node@18.12.1
actions:
disabled:
- trunk-announce
- trunk-check-pre-push
- trunk-fmt-pre-commit
enabled:
- trunk-upgrade-available

View File

@@ -2,10 +2,8 @@
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"ms-vscode.cpptools",
"platformio.platformio-ide",
"xaver.clang-format"
"trunk.io"
],
"unwantedRecommendations": [
"ms-vscode.cpptools-extension-pack"
]
}

82
.vscode/settings.json vendored
View File

@@ -1,80 +1,4 @@
{
"files.associations": {
"type_traits": "cpp",
"array": "cpp",
"*.tcc": "cpp",
"cctype": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"deque": "cpp",
"unordered_map": "cpp",
"unordered_set": "cpp",
"vector": "cpp",
"exception": "cpp",
"algorithm": "cpp",
"functional": "cpp",
"system_error": "cpp",
"tuple": "cpp",
"fstream": "cpp",
"initializer_list": "cpp",
"iomanip": "cpp",
"iosfwd": "cpp",
"istream": "cpp",
"limits": "cpp",
"memory": "cpp",
"new": "cpp",
"ostream": "cpp",
"numeric": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"streambuf": "cpp",
"cinttypes": "cpp",
"utility": "cpp",
"typeinfo": "cpp",
"string": "cpp",
"*.xbm": "cpp",
"list": "cpp",
"atomic": "cpp",
"memory_resource": "cpp",
"optional": "cpp",
"string_view": "cpp",
"cassert": "cpp",
"iterator": "cpp",
"shared_mutex": "cpp",
"iostream": "cpp",
"esp_nimble_hci.h": "c",
"map": "cpp",
"random": "cpp",
"*.tpp": "cpp"
},
"cSpell.words": [
"Blox",
"EINK",
"HFSR",
"Meshtastic",
"NEMAGPS",
"NMEAGPS",
"RDEF",
"Ublox",
"bkpt",
"cfsr",
"descs",
"ocrypto",
"protobufs",
"wifi"
],
"C_Cpp.dimInactiveRegions": true,
"cmake.configureOnOpen": true,
"protoc": {
"compile_on_save": false,
}
}
"editor.formatOnSave": true,
"editor.defaultFormatter": "trunk.io"
}

30
.vscode/tasks.json vendored
View File

@@ -1,17 +1,15 @@
{
"version": "2.0.0",
"tasks": [
{
"type": "PlatformIO",
"task": "Build",
"problemMatcher": [
"$platformio"
],
"group": {
"kind": "build",
"isDefault": true
},
"label": "PlatformIO: Build"
}
]
}
"version": "2.0.0",
"tasks": [
{
"type": "PlatformIO",
"task": "Build",
"problemMatcher": ["$platformio"],
"group": {
"kind": "build",
"isDefault": true
},
"label": "PlatformIO: Build"
}
]
}

View File

@@ -1,7 +1,7 @@
; Common settings for ESP targes, mixin with extends = esp32_base
[esp32_base]
extends = arduino_base
platform = platformio/espressif32@^5.2.0
platform = platformio/espressif32@^6.0.0
build_src_filter =
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2040> -<mesh/eth/>
upload_speed = 921600
@@ -26,6 +26,7 @@ build_flags =
-DCONFIG_NIMBLE_CPP_LOG_LEVEL=2
-DCONFIG_BT_NIMBLE_MAX_CCCDS=20
-DESP_OPENSSL_SUPPRESS_LEGACY_WARNING
;-DDEBUG_HEAP
lib_deps =
${arduino_base.lib_deps}

View File

@@ -1,6 +1,6 @@
[esp32s2_base]
extends = arduino_base
platform = platformio/espressif32@^5.2.0
platform = platformio/espressif32@^6.0.0
build_src_filter =
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2040> -<mesh/eth/> -<nimble/>
upload_speed = 961200
@@ -27,6 +27,7 @@ build_flags =
-DCONFIG_BT_NIMBLE_MAX_CCCDS=20
-DESP_OPENSSL_SUPPRESS_LEGACY_WARNING
-DHAS_BLUETOOTH=0
;-DDEBUG_HEAP
lib_deps =
${arduino_base.lib_deps}

View File

@@ -1,6 +1,6 @@
[esp32s3_base]
extends = arduino_base
platform = platformio/espressif32@^5.2.0
platform = platformio/espressif32@^6.0.0
build_src_filter =
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2040> -<mesh/eth/>
upload_speed = 961200
@@ -26,6 +26,7 @@ build_flags =
-DCONFIG_NIMBLE_CPP_LOG_LEVEL=2
-DCONFIG_BT_NIMBLE_MAX_CCCDS=20
-DESP_OPENSSL_SUPPRESS_LEGACY_WARNING
;-DDEBUG_HEAP
lib_deps =
${arduino_base.lib_deps}

View File

@@ -8,7 +8,7 @@ build_flags =
${arduino_base.build_flags} -Wno-unused-variable
-Isrc/platform/nrf52
build_src_filter =
${arduino_base.build_src_filter} -<platform/esp32/> -<platform/stm32wl> -<nimble/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mqtt/> -<platform/rp2040> -<mesh/eth/>
${arduino_base.build_src_filter} -<platform/esp32/> -<platform/stm32wl> -<nimble/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<mqtt/> -<platform/rp2040> -<mesh/eth/>
lib_ignore =
BluetoothOTA

View File

@@ -12,10 +12,12 @@ build_src_filter =
-<mesh/http/>
-<mesh/eth/>
-<modules/esp32>
-<modules/Telemetry>
-<modules/Telemetry/EnvironmentTelemetry.cpp>
-<modules/Telemetry/AirQualityTelemetry.cpp>
-<modules/Telemetry/Sensor>
+<../variants/portduino>
lib_deps =
${env.lib_deps}
${networking_base.lib_deps}
rweather/Crypto@^0.4.0
build_flags = ${arduino_base.build_flags} -Isrc/platform/portduino
build_flags = ${arduino_base.build_flags} -fPIC -Isrc/platform/portduino

View File

@@ -1,8 +1,6 @@
; Common settings for rp2040 Processor based targets
[rp2040_base]
platform = https://github.com/maxgerhardt/platform-raspberrypi.git#20c7dbfcfe6677c5305fa28ecf5e3870321cb157
platform_packages =
earlephilhower/toolchain-rp2040-earlephilhower@^5.100300.221223
platform = https://github.com/maxgerhardt/platform-raspberrypi.git#9f8c10e50b5acd18e7bfd32638199c655be73a5b
extends = arduino_base
board_build.core = earlephilhower
board_build.filesystem_size = 0.5m
@@ -12,7 +10,7 @@ build_flags =
-D__PLAT_RP2040__
# -D _POSIX_THREADS
build_src_filter =
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mqtt/> -<platform/nrf52/> -<platform/stm32wl> -<mesh/eth/>
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<mqtt/> -<platform/nrf52/> -<platform/stm32wl> -<mesh/eth/>
lib_ignore =
BluetoothOTA
lib_deps =

View File

@@ -10,7 +10,7 @@ build_flags =
# Arduino/PlatformIO framework-arduinoststm32 package does not presently have SUBGHZSPI support
# -DPIN_SPI_MOSI=PINSUBGHZSPIMOSI -DPIN_SPI_MISO=PINSUBGHZSPIMISO -DPIN_SPI_SCK=PINSUBGHZSPISCK
build_src_filter =
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mesh/eth/> -<mqtt/> -<graphics> -<input> -<buzz> -<modules/Telemetry> -<platform/nrf52> -<platform/portduino> -<platform/rp2040>
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<mesh/eth/> -<mqtt/> -<graphics> -<input> -<buzz> -<modules/Telemetry> -<platform/nrf52> -<platform/portduino> -<platform/rp2040>
lib_deps =
${env.lib_deps}
https://github.com/kokke/tiny-AES-c.git#f06ac37fc31dfdaca2e0d9bec83f90d5663c319b

View File

@@ -22,9 +22,9 @@ def readProps(prefsLoc):
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"
# 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)
except:

View File

@@ -1 +1,5 @@
cd protobufs && ..\nanopb-0.4.7\generator-bin\protoc.exe --nanopb_out=-v:..\src\mesh\generated -I=..\protobufs *.proto
cd protobufs && ..\nanopb-0.4.7\generator-bin\protoc.exe --nanopb_out=-v:..\src\mesh\generated -I=..\protobufs ..\protobufs\meshtastic\*.proto
@REM cd ../src/mesh/generated/meshtastic
@REM sed -i 's/#include "meshtastic/#include "./g' *
@REM sed -i 's/meshtastic_//g' *

View File

@@ -8,7 +8,12 @@ echo "prebuilt binaries for your computer into nanopb-0.4.7"
# the nanopb tool seems to require that the .options file be in the current directory!
cd protobufs
../nanopb-0.4.7/generator-bin/protoc --nanopb_out=-v:../src/mesh/generated -I=../protobufs *.proto
../nanopb-0.4.7/generator-bin/protoc --nanopb_out=-v:../src/mesh/generated/ -I=../protobufs meshtastic/*.proto
# cd ../src/mesh/generated/meshtastic
# sed -i 's/#include "meshtastic/#include "./g' -- *
# sed -i 's/meshtastic_//g' -- *
#echo "Regenerating protobuf documentation - if you see an error message"
#echo "you can ignore it unless doing a new protobuf release to github."

View File

@@ -7,12 +7,7 @@
"cpu": "cortex-m4",
"extra_flags": "-DARDUINO_NRF52840_TTGO_EINK -DNRF52840_XXAA",
"f_cpu": "64000000L",
"hwids": [
[
"0x239A",
"0x4405"
]
],
"hwids": [["0x239A", "0x4405"]],
"usb_product": "TTGO_eink",
"mcu": "nrf52840",
"variant": "eink0.1",
@@ -30,19 +25,13 @@
"settings_addr": "0xFF000"
}
},
"connectivity": [
"bluetooth"
],
"connectivity": ["bluetooth"],
"debug": {
"jlink_device": "nRF52840_xxAA",
"onboard_tools": [
"jlink"
],
"onboard_tools": ["jlink"],
"svd_path": "nrf52840.svd"
},
"frameworks": [
"arduino"
],
"frameworks": ["arduino"],
"name": "TTGO eink (Adafruit BSP)",
"upload": {
"maximum_ram_size": 248832,
@@ -50,12 +39,8 @@
"require_upload_port": true,
"speed": 115200,
"protocol": "jlink",
"protocols": [
"jlink",
"nrfjprog",
"stlink"
]
"protocols": ["jlink", "nrfjprog", "stlink"]
},
"url": "FIXME",
"vendor": "TTGO"
}
}

View File

@@ -9,9 +9,7 @@
"product_line": "STM32WLE5xx"
},
"debug": {
"default_tools": [
"stlink"
],
"default_tools": ["stlink"],
"jlink_device": "STM32WLE5CC",
"openocd_target": "stm32wlx",
"svd_path": "STM32WLE5_CM4.svd"
@@ -22,9 +20,7 @@
"maximum_ram_size": 65536,
"maximum_size": 262144,
"protocol": "cmsis-dap",
"protocols": [
"cmsis-dap"
]
"protocols": ["cmsis-dap"]
},
"url": "https://www.st.com/en/microcontrollers-microprocessors/stm32wl-series.html",
"vendor": "ST"

View File

@@ -19,16 +19,12 @@
"sd_fwid": "0x00B7"
}
},
"connectivity": [
"bluetooth"
],
"connectivity": ["bluetooth"],
"debug": {
"jlink_device": "nRF52832_xxAA",
"svd_path": "nrf52.svd"
},
"frameworks": [
"arduino"
],
"frameworks": ["arduino"],
"name": "lora ISP4520",
"upload": {
"maximum_ram_size": 65536,
@@ -36,13 +32,8 @@
"require_upload_port": true,
"speed": 115200,
"protocol": "nrfutil",
"protocols": [
"jlink",
"nrfjprog",
"nrfutil",
"stlink"
]
"protocols": ["jlink", "nrfjprog", "nrfutil", "stlink"]
},
"url": "",
"vendor": "PsiSoft"
}
}

View File

@@ -1,72 +1,51 @@
{
"build": {
"arduino": {
"ldscript": "nrf52840_s140_v6.ld"
},
"core": "nRF5",
"cpu": "cortex-m4",
"extra_flags": "-DARDUINO_NRF52840_FEATHER -DNRF52840_XXAA",
"f_cpu": "64000000L",
"hwids": [
[
"0x239A",
"0x8029"
],
[
"0x239A",
"0x0029"
],
[
"0x239A",
"0x002A"
],
[
"0x239A",
"0x802A"
]
],
"usb_product": "PCA10059",
"mcu": "nrf52840",
"variant": "nRF52840 Dongle",
"bsp": {
"name": "adafruit"
},
"softdevice": {
"sd_flags": "-DS140",
"sd_name": "s140",
"sd_version": "6.1.1",
"sd_fwid": "0x00B6"
},
"bootloader": {
"settings_addr": "0xFF000"
}
"build": {
"arduino": {
"ldscript": "nrf52840_s140_v6.ld"
},
"connectivity": [
"bluetooth"
"core": "nRF5",
"cpu": "cortex-m4",
"extra_flags": "-DARDUINO_NRF52840_FEATHER -DNRF52840_XXAA",
"f_cpu": "64000000L",
"hwids": [
["0x239A", "0x8029"],
["0x239A", "0x0029"],
["0x239A", "0x002A"],
["0x239A", "0x802A"]
],
"debug": {
"jlink_device": "nRF52840_xxAA",
"svd_path": "nrf52840.svd"
"usb_product": "PCA10059",
"mcu": "nrf52840",
"variant": "nRF52840 Dongle",
"bsp": {
"name": "adafruit"
},
"frameworks": [
"arduino"
],
"name": "nRF52840 Dongle",
"upload": {
"maximum_ram_size": 248832,
"maximum_size": 815104,
"speed": 115200,
"protocol": "nrfutil",
"protocols": [
"jlink",
"nrfjprog",
"nrfutil",
"stlink"
],
"use_1200bps_touch": true,
"require_upload_port": true,
"wait_for_upload_port": true
"softdevice": {
"sd_flags": "-DS140",
"sd_name": "s140",
"sd_version": "6.1.1",
"sd_fwid": "0x00B6"
},
"url": "https://www.nordicsemi.com/Products/Development-hardware/nrf52840-dongle",
"vendor": "Nordic Semiconductor"
"bootloader": {
"settings_addr": "0xFF000"
}
},
"connectivity": ["bluetooth"],
"debug": {
"jlink_device": "nRF52840_xxAA",
"svd_path": "nrf52840.svd"
},
"frameworks": ["arduino"],
"name": "nRF52840 Dongle",
"upload": {
"maximum_ram_size": 248832,
"maximum_size": 815104,
"speed": 115200,
"protocol": "nrfutil",
"protocols": ["jlink", "nrfjprog", "nrfutil", "stlink"],
"use_1200bps_touch": true,
"require_upload_port": true,
"wait_for_upload_port": true
},
"url": "https://www.nordicsemi.com/Products/Development-hardware/nrf52840-dongle",
"vendor": "Nordic Semiconductor"
}

View File

@@ -1,47 +1,46 @@
{
"build": {
"arduino": {
"ldscript": "nrf52840_s140_v6.ld"
},
"core": "nRF5",
"cpu": "cortex-m4",
"extra_flags": "-DARDUINO_NRF52840_PCA10056 -DNRF52840_XXAA",
"f_cpu": "64000000L",
"hwids": [["0x239A", "0x4404"]],
"usb_product": "nrf52840dk",
"mcu": "nrf52840",
"variant": "pca10056",
"variants_dir": "variants",
"bsp": {
"name": "adafruit"
},
"softdevice": {
"sd_flags": "-DS140",
"sd_name": "s140",
"sd_version": "6.1.1",
"sd_fwid": "0x00B6"
},
"bootloader": {
"settings_addr": "0xFF000"
}
"build": {
"arduino": {
"ldscript": "nrf52840_s140_v6.ld"
},
"connectivity": ["bluetooth"],
"debug": {
"jlink_device": "nRF52840_xxAA",
"onboard_tools": ["jlink"],
"svd_path": "nrf52840.svd"
"core": "nRF5",
"cpu": "cortex-m4",
"extra_flags": "-DARDUINO_NRF52840_PCA10056 -DNRF52840_XXAA",
"f_cpu": "64000000L",
"hwids": [["0x239A", "0x4404"]],
"usb_product": "nrf52840dk",
"mcu": "nrf52840",
"variant": "pca10056",
"variants_dir": "variants",
"bsp": {
"name": "adafruit"
},
"frameworks": ["arduino"],
"name": "A modified NRF52840-DK devboard (Adafruit BSP)",
"upload": {
"maximum_ram_size": 248832,
"maximum_size": 815104,
"require_upload_port": true,
"speed": 115200,
"protocol": "jlink",
"protocols": ["jlink", "nrfjprog", "stlink"]
"softdevice": {
"sd_flags": "-DS140",
"sd_name": "s140",
"sd_version": "6.1.1",
"sd_fwid": "0x00B6"
},
"url": "https://meshtastic.org/",
"vendor": "Nordic Semi"
}
"bootloader": {
"settings_addr": "0xFF000"
}
},
"connectivity": ["bluetooth"],
"debug": {
"jlink_device": "nRF52840_xxAA",
"onboard_tools": ["jlink"],
"svd_path": "nrf52840.svd"
},
"frameworks": ["arduino"],
"name": "A modified NRF52840-DK devboard (Adafruit BSP)",
"upload": {
"maximum_ram_size": 248832,
"maximum_size": 815104,
"require_upload_port": true,
"speed": 115200,
"protocol": "jlink",
"protocols": ["jlink", "nrfjprog", "stlink"]
},
"url": "https://meshtastic.org/",
"vendor": "Nordic Semi"
}

View File

@@ -7,12 +7,7 @@
"cpu": "cortex-m4",
"extra_flags": "-DARDUINO_NRF52840_TTGO_EINK -DNRF52840_XXAA",
"f_cpu": "64000000L",
"hwids": [
[
"0x239A",
"0x4405"
]
],
"hwids": [["0x239A", "0x4405"]],
"usb_product": "TTGO_eink",
"mcu": "nrf52840",
"variant": "t-echo",
@@ -30,35 +25,24 @@
"settings_addr": "0xFF000"
}
},
"connectivity": [
"bluetooth"
],
"connectivity": ["bluetooth"],
"debug": {
"jlink_device": "nRF52840_xxAA",
"onboard_tools": [
"jlink"
],
"onboard_tools": ["jlink"],
"svd_path": "nrf52840.svd"
},
"frameworks": [
"arduino"
],
"frameworks": ["arduino"],
"name": "TTGO eink (Adafruit BSP)",
"upload": {
"maximum_ram_size": 248832,
"maximum_size": 815104,
"speed": 115200,
"protocol": "nrfutil",
"protocols": [
"jlink",
"nrfjprog",
"nrfutil",
"stlink"
],
"use_1200bps_touch": true,
"require_upload_port": true,
"wait_for_upload_port": true
"upload": {
"maximum_ram_size": 248832,
"maximum_size": 815104,
"speed": 115200,
"protocol": "nrfutil",
"protocols": ["jlink", "nrfjprog", "nrfutil", "stlink"],
"use_1200bps_touch": true,
"require_upload_port": true,
"wait_for_upload_port": true
},
"url": "FIXME",
"vendor": "TTGO"
}
}

View File

@@ -15,24 +15,15 @@
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "dio",
"hwids": [
[
"0X303A",
"0x1001"
]
],
"hwids": [["0X303A", "0x1001"]],
"mcu": "esp32s3",
"variant": "tbeam-s3-core"
},
"connectivity": [
"wifi"
],
"connectivity": ["wifi"],
"debug": {
"openocd_target": "esp32s3.cfg"
},
"frameworks": [
"arduino"
],
"frameworks": ["arduino"],
"name": "LilyGo TBeam-S3-Core",
"upload": {
"flash_size": "8MB",
@@ -43,4 +34,4 @@
},
"url": "http://www.lilygo.cn/",
"vendor": "LilyGo"
}
}

View File

@@ -14,25 +14,15 @@
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "dio",
"hwids": [
[
"0X303A",
"0x1001"
]
],
"hwids": [["0x303A", "0x1001"]],
"mcu": "esp32s3",
"variant": "tlora-t3s3-v1"
},
"connectivity": [
"wifi"
],
"connectivity": ["wifi"],
"debug": {
"openocd_target": "esp32s3.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"frameworks": ["arduino", "espidf"],
"name": "LilyGo TLora-T3S3-V1",
"upload": {
"flash_size": "4MB",
@@ -44,4 +34,4 @@
},
"url": "http://www.lilygo.cn/",
"vendor": "LilyGo"
}
}

View File

@@ -1,6 +1,6 @@
{
"build": {
"arduino":{
"arduino": {
"ldscript": "esp32_out.ld"
},
"core": "esp32",
@@ -11,26 +11,14 @@
"mcu": "esp32",
"variant": "WisCore_RAK11200_Board"
},
"connectivity": [
"wifi",
"bluetooth",
"ethernet",
"can"
],
"frameworks": [
"arduino",
"espidf"
],
"connectivity": ["wifi", "bluetooth", "ethernet", "can"],
"frameworks": ["arduino", "espidf"],
"name": "WisCore RAK11200 Board",
"upload": {
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"protocols": [
"esptool",
"espota",
"ftdi"
],
"protocols": ["esptool", "espota", "ftdi"],
"require_upload_port": true,
"speed": 460800
},

View File

@@ -8,22 +8,10 @@
"extra_flags": "-DNRF52832_XXAA -DNRF52",
"f_cpu": "64000000L",
"hwids": [
[
"0x239A",
"0x8029"
],
[
"0x239A",
"0x0029"
],
[
"0x239A",
"0x002A"
],
[
"0x239A",
"0x802A"
]
["0x239A", "0x8029"],
["0x239A", "0x0029"],
["0x239A", "0x002A"],
["0x239A", "0x802A"]
],
"usb_product": "Feather nRF52832 Express",
"mcu": "nrf52832",
@@ -41,17 +29,12 @@
"variant": "nrf52_adafruit_feather"
}
},
"connectivity": [
"bluetooth"
],
"connectivity": ["bluetooth"],
"debug": {
"jlink_device": "nRF52832_xxAA",
"svd_path": "nrf52.svd"
},
"frameworks": [
"arduino",
"zephyr"
],
"frameworks": ["arduino", "zephyr"],
"name": "Adafruit Bluefruit nRF52832 Feather",
"upload": {
"maximum_ram_size": 65536,
@@ -59,13 +42,8 @@
"require_upload_port": true,
"speed": 115200,
"protocol": "nrfutil",
"protocols": [
"jlink",
"nrfjprog",
"nrfutil",
"stlink"
]
"protocols": ["jlink", "nrfjprog", "nrfutil", "stlink"]
},
"url": "https://www.adafruit.com/product/3406",
"vendor": "Adafruit"
}
}

View File

@@ -1,72 +1,51 @@
{
"build": {
"arduino": {
"ldscript": "nrf52840_s140_v6.ld"
},
"core": "nRF5",
"cpu": "cortex-m4",
"extra_flags": "-DARDUINO_NRF52840_FEATHER -DNRF52840_XXAA",
"f_cpu": "64000000L",
"hwids": [
[
"0x239A",
"0x8029"
],
[
"0x239A",
"0x0029"
],
[
"0x239A",
"0x002A"
],
[
"0x239A",
"0x802A"
]
],
"usb_product": "WisCore RAK4631 Board",
"mcu": "nrf52840",
"variant": "WisCore_RAK4631_Board",
"bsp": {
"name": "adafruit"
},
"softdevice": {
"sd_flags": "-DS140",
"sd_name": "s140",
"sd_version": "6.1.1",
"sd_fwid": "0x00B6"
},
"bootloader": {
"settings_addr": "0xFF000"
}
"build": {
"arduino": {
"ldscript": "nrf52840_s140_v6.ld"
},
"connectivity": [
"bluetooth"
"core": "nRF5",
"cpu": "cortex-m4",
"extra_flags": "-DARDUINO_NRF52840_FEATHER -DNRF52840_XXAA",
"f_cpu": "64000000L",
"hwids": [
["0x239A", "0x8029"],
["0x239A", "0x0029"],
["0x239A", "0x002A"],
["0x239A", "0x802A"]
],
"debug": {
"jlink_device": "nRF52840_xxAA",
"svd_path": "nrf52840.svd"
"usb_product": "WisCore RAK4631 Board",
"mcu": "nrf52840",
"variant": "WisCore_RAK4631_Board",
"bsp": {
"name": "adafruit"
},
"frameworks": [
"arduino"
],
"name": "WisCore RAK4631 Board",
"upload": {
"maximum_ram_size": 248832,
"maximum_size": 815104,
"speed": 115200,
"protocol": "nrfutil",
"protocols": [
"jlink",
"nrfjprog",
"nrfutil",
"stlink"
],
"use_1200bps_touch": true,
"require_upload_port": true,
"wait_for_upload_port": true
"softdevice": {
"sd_flags": "-DS140",
"sd_name": "s140",
"sd_version": "6.1.1",
"sd_fwid": "0x00B6"
},
"url": "https://www.rakwireless.com",
"vendor": "RAKwireless"
}
"bootloader": {
"settings_addr": "0xFF000"
}
},
"connectivity": ["bluetooth"],
"debug": {
"jlink_device": "nRF52840_xxAA",
"svd_path": "nrf52840.svd"
},
"frameworks": ["arduino"],
"name": "WisCore RAK4631 Board",
"upload": {
"maximum_ram_size": 248832,
"maximum_size": 815104,
"speed": 115200,
"protocol": "nrfutil",
"protocols": ["jlink", "nrfjprog", "nrfutil", "stlink"],
"use_1200bps_touch": true,
"require_upload_port": true,
"wait_for_upload_port": true
},
"url": "https://www.rakwireless.com",
"vendor": "RAKwireless"
}

View File

@@ -8,6 +8,6 @@ services:
replicas: 4
networks:
- mesh
networks:
mesh:
mesh:

View File

@@ -2,7 +2,7 @@
; https://docs.platformio.org/page/projectconf.html
[platformio]
;default_envs = tbeam
default_envs = tbeam
;default_envs = pico
;default_envs = tbeam-s3-core
;default_envs = tbeam0.7
@@ -13,6 +13,7 @@
;default_envs = tlora_v1_3
;default_envs = tlora-v2
;default_envs = tlora-v2-1-1.6
;default_envs = tlora-t3s3-v1
;default_envs = lora-relay-v1 # nrf board
;default_envs = t-echo
;default_envs = nrf52840dk-geeksville
@@ -39,7 +40,7 @@ extra_scripts = bin/platformio-custom.py
; The Radiolib stuff will speed up building considerably. Exclud all the stuff we dont need.
build_flags = -Wno-missing-field-initializers
-Wno-format
-Isrc -Isrc/mesh -Isrc/gps -Isrc/buzz -Wl,-Map,.pio/build/output.map
-Isrc -Isrc/mesh -Isrc/mesh/generated -Isrc/gps -Isrc/buzz -Wl,-Map,.pio/build/output.map
-DUSE_THREAD_NAMES
-DTINYGPS_OPTION_NO_CUSTOM_FIELDS
-DPB_ENABLE_MALLOC=1
@@ -58,7 +59,7 @@ build_flags = -Wno-missing-field-initializers
monitor_speed = 115200
lib_deps =
https://github.com/meshtastic/esp8266-oled-ssd1306.git#53580644255b48ebb7a737343c6b4e71c7e11cf2 ; ESP8266_SSD1306
https://github.com/meshtastic/esp8266-oled-ssd1306.git#da1ede4dfcd91074283b029080759fd744120909 ; ESP8266_SSD1306
mathertel/OneButton@^2.0.3 ; OneButton library for non-blocking button debounce
https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159
https://github.com/meshtastic/TinyGPSPlus.git#127ad674ef85f0201cb68a065879653ed94792c4
@@ -66,7 +67,7 @@ lib_deps =
nanopb/Nanopb@^0.4.6
erriez/ErriezCRC32@^1.0.1
; jgromes/RadioLib@^5.5.1
https://github.com/jgromes/RadioLib.git#395844922c5d88d5db0481a9c91479931172428d
https://github.com/jgromes/RadioLib.git#1afa947030c5637f71f6563bc22aa75032e53a57
; Used for the code analysis in PIO Home / Inspect
check_tool = cppcheck
@@ -93,6 +94,7 @@ build_src_filter = ${env.build_src_filter} -<platform/portduino/>
lib_deps =
knolleary/PubSubClient@^2.8
arduino-libraries/NTPClient@^3.1.0
arcao/Syslog@^2.0.0
; Common libs for environmental measurements in telemetry module
; (not included in native / portduino)
@@ -109,3 +111,4 @@ lib_deps =
adafruit/Adafruit SHTC3 Library@^1.0.0
adafruit/Adafruit LPS2X@^2.0.4
adafruit/Adafruit SHT31 Library@^2.2.0
adafruit/Adafruit PM25 AQI Sensor@^1.0.6

View File

@@ -1,5 +1,5 @@
#include "configuration.h"
#include "BluetoothCommon.h"
#include "configuration.h"
// NRF52 wants these constants as byte arrays
// Generated here https://yupana-engineering.com/online-uuid-to-c-array-converter - but in REVERSE BYTE ORDER

View File

@@ -17,4 +17,14 @@
extern const uint8_t MESH_SERVICE_UUID_16[], TORADIO_UUID_16[16u], FROMRADIO_UUID_16[], FROMNUM_UUID_16[];
/// Given a level between 0-100, update the BLE attribute
void updateBatteryLevel(uint8_t level);
void updateBatteryLevel(uint8_t level);
class BluetoothApi
{
public:
virtual void setup();
virtual void shutdown();
virtual void clearBonds();
virtual bool isConnected();
virtual int getRssi() = 0;
};

View File

@@ -115,8 +115,7 @@ class ButtonThread : public concurrency::OSThread
{
// LOG_DEBUG("press!\n");
#ifdef BUTTON_PIN
if ((BUTTON_PIN != moduleConfig.canned_message.inputbroker_pin_press) ||
!moduleConfig.canned_message.enabled) {
if ((BUTTON_PIN != moduleConfig.canned_message.inputbroker_pin_press) || !moduleConfig.canned_message.enabled) {
powerFSM.trigger(EVENT_PRESS);
}
#endif
@@ -144,10 +143,10 @@ class ButtonThread : public concurrency::OSThread
#ifdef PIN_LED1
ledOff(PIN_LED1);
#endif
#ifdef PIN_LED2
#ifdef PIN_LED2
ledOff(PIN_LED2);
#endif
#ifdef PIN_LED3
#ifdef PIN_LED3
ledOff(PIN_LED3);
#endif
shutdown_on_long_stop = true;
@@ -160,28 +159,25 @@ class ButtonThread : public concurrency::OSThread
static void userButtonDoublePressed()
{
#if defined(USE_EINK) && defined(PIN_EINK_EN)
#if defined(USE_EINK) && defined(PIN_EINK_EN)
digitalWrite(PIN_EINK_EN, digitalRead(PIN_EINK_EN) == LOW);
#endif
#if defined(GPS_POWER_TOGGLE)
if(config.position.gps_enabled)
{
LOG_DEBUG("Flag set to false for gps power\n");
}
else
{
LOG_DEBUG("Flag set to true to restore power\n");
}
config.position.gps_enabled = !(config.position.gps_enabled);
doGPSpowersave(config.position.gps_enabled);
#endif
#endif
screen->print("Sent ad-hoc ping\n");
service.refreshMyNodeInfo();
service.sendNetworkPing(NODENUM_BROADCAST, true);
}
static void userButtonMultiPressed()
{
screen->print("Sent ad-hoc ping\n");
service.refreshMyNodeInfo();
service.sendNetworkPing(NODENUM_BROADCAST, true);
#if defined(GPS_POWER_TOGGLE)
if (config.position.gps_enabled) {
LOG_DEBUG("Flag set to false for gps power\n");
} else {
LOG_DEBUG("Flag set to true to restore power\n");
}
config.position.gps_enabled = !(config.position.gps_enabled);
doGPSpowersave(config.position.gps_enabled);
#endif
}
static void userButtonPressedLongStart()

172
src/DebugConfiguration.cpp Normal file
View File

@@ -0,0 +1,172 @@
/* based on https://github.com/arcao/Syslog
MIT License
Copyright (c) 2016 Martin Sloup
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.*/
#include "configuration.h"
#include "DebugConfiguration.h"
#if HAS_WIFI || HAS_ETHERNET
Syslog::Syslog(UDP &client)
{
this->_client = &client;
this->_server = NULL;
this->_port = 0;
this->_deviceHostname = SYSLOG_NILVALUE;
this->_appName = SYSLOG_NILVALUE;
this->_priDefault = LOGLEVEL_KERN;
}
Syslog &Syslog::server(const char *server, uint16_t port)
{
if (this->_ip.fromString(server)) {
this->_server = NULL;
} else {
this->_server = server;
}
this->_port = port;
return *this;
}
Syslog &Syslog::server(IPAddress ip, uint16_t port)
{
this->_ip = ip;
this->_server = NULL;
this->_port = port;
return *this;
}
Syslog &Syslog::deviceHostname(const char *deviceHostname)
{
this->_deviceHostname = (deviceHostname == NULL) ? SYSLOG_NILVALUE : deviceHostname;
return *this;
}
Syslog &Syslog::appName(const char *appName)
{
this->_appName = (appName == NULL) ? SYSLOG_NILVALUE : appName;
return *this;
}
Syslog &Syslog::defaultPriority(uint16_t pri)
{
this->_priDefault = pri;
return *this;
}
Syslog &Syslog::logMask(uint8_t priMask)
{
this->_priMask = priMask;
return *this;
}
void Syslog::enable()
{
this->_enabled = true;
}
void Syslog::disable()
{
this->_enabled = false;
}
bool Syslog::isEnabled()
{
return this->_enabled;
}
bool Syslog::vlogf(uint16_t pri, const char *fmt, va_list args)
{
return this->vlogf(pri, this->_appName, fmt, args);
}
bool Syslog::vlogf(uint16_t pri, const char *appName, const char *fmt, va_list args)
{
char *message;
size_t initialLen;
size_t len;
bool result;
initialLen = strlen(fmt);
message = new char[initialLen + 1];
len = vsnprintf(message, initialLen + 1, fmt, args);
if (len > initialLen) {
delete[] message;
message = new char[len + 1];
vsnprintf(message, len + 1, fmt, args);
}
result = this->_sendLog(pri, appName, message);
delete[] message;
return result;
}
inline bool Syslog::_sendLog(uint16_t pri, const char *appName, const char *message)
{
int result;
if (!this->_enabled)
return false;
if ((this->_server == NULL && this->_ip == INADDR_NONE) || this->_port == 0)
return false;
// Check priority against priMask values.
if ((LOG_MASK(LOG_PRI(pri)) & this->_priMask) == 0)
return true;
// Set default facility if none specified.
if ((pri & LOG_FACMASK) == 0)
pri = LOG_MAKEPRI(LOG_FAC(this->_priDefault), pri);
if (this->_server != NULL) {
result = this->_client->beginPacket(this->_server, this->_port);
} else {
result = this->_client->beginPacket(this->_ip, this->_port);
}
if (result != 1)
return false;
this->_client->print('<');
this->_client->print(pri);
this->_client->print(F(">1 - "));
this->_client->print(this->_deviceHostname);
this->_client->print(' ');
this->_client->print(appName);
this->_client->print(F(" - - - \xEF\xBB\xBF"));
this->_client->print(F("["));
this->_client->print(int(millis() / 1000));
this->_client->print(F("]: "));
this->_client->print(message);
this->_client->endPacket();
return true;
}
#endif

View File

@@ -1,3 +1,6 @@
#ifndef SYSLOG_H
#define SYSLOG_H
// DEBUG LED
#ifndef LED_INVERTED
#define LED_INVERTED 0 // define as 1 if LED is active low (on)
@@ -17,6 +20,7 @@
#define MESHTASTIC_LOG_LEVEL_INFO "INFO "
#define MESHTASTIC_LOG_LEVEL_WARN "WARN "
#define MESHTASTIC_LOG_LEVEL_ERROR "ERROR"
#define MESHTASTIC_LOG_LEVEL_CRIT "CRIT "
#define MESHTASTIC_LOG_LEVEL_TRACE "TRACE"
#include "SerialConsole.h"
@@ -28,21 +32,72 @@
#define LOG_INFO(...) SEGGER_RTT_printf(0, __VA_ARGS__)
#define LOG_WARN(...) SEGGER_RTT_printf(0, __VA_ARGS__)
#define LOG_ERROR(...) SEGGER_RTT_printf(0, __VA_ARGS__)
#define LOG_CRIT(...) SEGGER_RTT_printf(0, __VA_ARGS__)
#define LOG_TRACE(...) SEGGER_RTT_printf(0, __VA_ARGS__)
#else
#ifdef DEBUG_PORT
#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__)
#define LOG_ERROR(...) DEBUG_PORT.log(MESHTASTIC_LOG_LEVEL_ERROR, __VA_ARGS__)
#define LOG_TRACE(...) DEBUG_PORT.log(MESHTASTIC_LOG_TRACE, __VA_ARGS__)
#define LOG_CRIT(...) DEBUG_PORT.log(MESHTASTIC_LOG_LEVEL_CRIT, __VA_ARGS__)
#define LOG_TRACE(...) DEBUG_PORT.log(MESHTASTIC_LOG_LEVEL_TRACE, __VA_ARGS__)
#else
#define LOG_DEBUG(...)
#define LOG_INFO(...)
#define LOG_WARN(...)
#define LOG_ERROR(...)
#define LOG_CRIT(...)
#define LOG_TRACE(...)
#endif
#endif
#define SYSLOG_NILVALUE "-"
#define SYSLOG_CRIT 2 /* critical conditions */
#define SYSLOG_ERR 3 /* error conditions */
#define SYSLOG_WARN 4 /* warning conditions */
#define SYSLOG_INFO 6 /* informational */
#define SYSLOG_DEBUG 7 /* debug-level messages */
// trace does not go out to syslog (yet?)
#define LOG_PRIMASK 0x07 /* mask to extract priority part (internal) */
/* extract priority */
#define LOG_PRI(p) ((p)&LOG_PRIMASK)
#define LOG_MAKEPRI(fac, pri) (((fac) << 3) | (pri))
/* facility codes */
#define LOGLEVEL_KERN (0 << 3) /* kernel messages */
#define LOGLEVEL_USER (1 << 3) /* random user-level messages */
#define LOGLEVEL_MAIL (2 << 3) /* mail system */
#define LOGLEVEL_DAEMON (3 << 3) /* system daemons */
#define LOGLEVEL_AUTH (4 << 3) /* security/authorization messages */
#define LOGLEVEL_SYSLOG (5 << 3) /* messages generated internally by syslogd */
#define LOGLEVEL_LPR (6 << 3) /* line printer subsystem */
#define LOGLEVEL_NEWS (7 << 3) /* network news subsystem */
#define LOGLEVEL_UUCP (8 << 3) /* UUCP subsystem */
#define LOGLEVEL_CRON (9 << 3) /* clock daemon */
#define LOGLEVEL_AUTHPRIV (10 << 3) /* security/authorization messages (private) */
#define LOGLEVEL_FTP (11 << 3) /* ftp daemon */
/* other codes through 15 reserved for system use */
#define LOGLEVEL_LOCAL0 (16 << 3) /* reserved for local use */
#define LOGLEVEL_LOCAL1 (17 << 3) /* reserved for local use */
#define LOGLEVEL_LOCAL2 (18 << 3) /* reserved for local use */
#define LOGLEVEL_LOCAL3 (19 << 3) /* reserved for local use */
#define LOGLEVEL_LOCAL4 (20 << 3) /* reserved for local use */
#define LOGLEVEL_LOCAL5 (21 << 3) /* reserved for local use */
#define LOGLEVEL_LOCAL6 (22 << 3) /* reserved for local use */
#define LOGLEVEL_LOCAL7 (23 << 3) /* reserved for local use */
#define LOG_NFACILITIES 24 /* current number of facilities */
#define LOG_FACMASK 0x03f8 /* mask to extract facility part */
/* facility of pri */
#define LOG_FAC(p) (((p)&LOG_FACMASK) >> 3)
#define LOG_MASK(pri) (1 << (pri)) /* mask for one priority */
#define LOG_UPTO(pri) ((1 << ((pri) + 1)) - 1) /* all priorities through pri */
// -----------------------------------------------------------------------------
// AXP192 (Rev1-specific options)
// -----------------------------------------------------------------------------
@@ -52,3 +107,50 @@
// Default Bluetooth PIN
#define defaultBLEPin 123456
#if HAS_ETHERNET
#include <RAK13800_W5100S.h>
#endif // HAS_ETHERNET
#if HAS_WIFI
#include <WiFi.h>
#endif // HAS_WIFI
#if HAS_WIFI || HAS_ETHERNET
class Syslog
{
private:
UDP *_client;
IPAddress _ip;
const char *_server;
uint16_t _port;
const char *_deviceHostname;
const char *_appName;
uint16_t _priDefault;
uint8_t _priMask = 0xff;
bool _enabled = false;
bool _sendLog(uint16_t pri, const char *appName, const char *message);
public:
explicit Syslog(UDP &client);
Syslog &server(const char *server, uint16_t port);
Syslog &server(IPAddress ip, uint16_t port);
Syslog &deviceHostname(const char *deviceHostname);
Syslog &appName(const char *appName);
Syslog &defaultPriority(uint16_t pri = LOGLEVEL_KERN);
Syslog &logMask(uint8_t priMask);
void enable();
void disable();
bool isEnabled();
bool vlogf(uint16_t pri, const char *fmt, va_list args) __attribute__((format(printf, 3, 0)));
bool vlogf(uint16_t pri, const char *appName, const char *fmt, va_list args) __attribute__((format(printf, 3, 0)));
};
#endif // HAS_ETHERNET || HAS_WIFI
#endif // SYSLOG_H

View File

@@ -1,26 +1,24 @@
#include "configuration.h"
#include "FSCommon.h"
#include "configuration.h"
#ifdef HAS_SDCARD
#include <SPI.h>
#include <SD.h>
#include <SPI.h>
#ifdef SDCARD_USE_SPI1
#ifdef SDCARD_USE_SPI1
SPIClass SPI1(HSPI);
#define SDHandler SPI1
#endif
#endif // HAS_SDCARD
#endif //HAS_SDCARD
bool copyFile(const char* from, const char* to)
bool copyFile(const char *from, const char *to)
{
#ifdef FSCom
unsigned char cbuffer[16];
File f1 = FSCom.open(from, FILE_O_READ);
if (!f1){
if (!f1) {
LOG_ERROR("Failed to open source file %s\n", from);
return false;
}
@@ -30,92 +28,92 @@ bool copyFile(const char* from, const char* to)
LOG_ERROR("Failed to open destination file %s\n", to);
return false;
}
while (f1.available() > 0) {
byte i = f1.read(cbuffer, 16);
f2.write(cbuffer, i);
}
f2.close();
f1.close();
return true;
#endif
}
bool renameFile(const char* pathFrom, const char* pathTo)
bool renameFile(const char *pathFrom, const char *pathTo)
{
#ifdef FSCom
#ifdef ARCH_ESP32
// rename was fixed for ESP32 IDF LittleFS in April
return FSCom.rename(pathFrom, pathTo);
#else
if (copyFile(pathFrom, pathTo) && FSCom.remove(pathFrom) ) {
if (copyFile(pathFrom, pathTo) && FSCom.remove(pathFrom)) {
return true;
} else{
} else {
return false;
}
#endif
#endif
}
void listDir(const char * dirname, uint8_t levels, boolean del = false)
void listDir(const char *dirname, uint8_t levels, boolean del = false)
{
#ifdef FSCom
#if (defined(ARCH_ESP32) || defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
char buffer[255];
#endif
File root = FSCom.open(dirname, FILE_O_READ);
if(!root){
if (!root) {
return;
}
if(!root.isDirectory()){
if (!root.isDirectory()) {
return;
}
File file = root.openNextFile();
while(file){
if(file.isDirectory() && !String(file.name()).endsWith(".")) {
if(levels){
while (file) {
if (file.isDirectory() && !String(file.name()).endsWith(".")) {
if (levels) {
#ifdef ARCH_ESP32
listDir(file.path(), levels -1, del);
if(del) {
listDir(file.path(), levels - 1, del);
if (del) {
LOG_DEBUG("Removing %s\n", file.path());
strcpy(buffer, file.path());
strncpy(buffer, file.path(), sizeof(buffer));
file.close();
FSCom.rmdir(buffer);
} else {
file.close();
}
#elif (defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
listDir(file.name(), levels -1, del);
if(del) {
listDir(file.name(), levels - 1, del);
if (del) {
LOG_DEBUG("Removing %s\n", file.name());
strcpy(buffer, file.name());
strncpy(buffer, file.name(), sizeof(buffer));
file.close();
FSCom.rmdir(buffer);
} else {
file.close();
}
}
#else
listDir(file.name(), levels -1, del);
listDir(file.name(), levels - 1, del);
file.close();
#endif
}
} else {
#ifdef ARCH_ESP32
if(del) {
if (del) {
LOG_DEBUG("Deleting %s\n", file.path());
strcpy(buffer, file.path());
strncpy(buffer, file.path(), sizeof(buffer));
file.close();
FSCom.remove(buffer);
} else {
LOG_DEBUG(" %s (%i Bytes)\n", file.path(), file.size());
LOG_DEBUG(" %s (%i Bytes)\n", file.path(), file.size());
file.close();
}
#elif (defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
if(del) {
if (del) {
LOG_DEBUG("Deleting %s\n", file.name());
strcpy(buffer, file.name());
strncpy(buffer, file.name(), sizeof(buffer));
file.close();
FSCom.remove(buffer);
} else {
@@ -125,23 +123,23 @@ void listDir(const char * dirname, uint8_t levels, boolean del = false)
#else
LOG_DEBUG(" %s (%i Bytes)\n", file.name(), file.size());
file.close();
#endif
#endif
}
file = root.openNextFile();
}
#ifdef ARCH_ESP32
if(del) {
#ifdef ARCH_ESP32
if (del) {
LOG_DEBUG("Removing %s\n", root.path());
strcpy(buffer, root.path());
strncpy(buffer, root.path(), sizeof(buffer));
root.close();
FSCom.rmdir(buffer);
} else {
root.close();
}
#elif (defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
if(del) {
if (del) {
LOG_DEBUG("Removing %s\n", root.name());
strcpy(buffer, root.name());
strncpy(buffer, root.name(), sizeof(buffer));
root.close();
FSCom.rmdir(buffer);
} else {
@@ -153,7 +151,7 @@ void listDir(const char * dirname, uint8_t levels, boolean del = false)
#endif
}
void rmDir(const char * dirname)
void rmDir(const char *dirname)
{
#ifdef FSCom
#if (defined(ARCH_ESP32) || defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
@@ -168,10 +166,9 @@ void rmDir(const char * dirname)
void fsInit()
{
#ifdef FSCom
if (!FSBegin())
{
LOG_ERROR("Filesystem mount Failed. Formatting...\n");
assert(0); // FIXME - report failure to phone
if (!FSBegin()) {
LOG_ERROR("Filesystem mount Failed.\n");
// assert(0); This auto-formats the partition, so no need to fail here.
}
#ifdef ARCH_ESP32
LOG_DEBUG("Filesystem files (%d/%d Bytes):\n", FSCom.usedBytes(), FSCom.totalBytes());
@@ -182,7 +179,6 @@ void fsInit()
#endif
}
void setupSDCard()
{
#ifdef HAS_SDCARD
@@ -190,12 +186,12 @@ void setupSDCard()
if (!SD.begin(SDCARD_CS, SDHandler)) {
LOG_DEBUG("No SD_MMC card detected\n");
return ;
return;
}
uint8_t cardType = SD.cardType();
if (cardType == CARD_NONE) {
LOG_DEBUG("No SD_MMC card attached\n");
return ;
return;
}
LOG_DEBUG("SD_MMC Card Type: ");
if (cardType == CARD_MMC) {
@@ -214,6 +210,3 @@ void setupSDCard()
LOG_DEBUG("Used space: %llu MB\n", SD.usedBytes() / (1024 * 1024));
#endif
}

View File

@@ -17,7 +17,7 @@
// RP2040
#include "LittleFS.h"
#define FSCom LittleFS
#define FSBegin() FSCom.begin()
#define FSBegin() FSCom.begin() // set autoformat
#define FILE_O_WRITE "w"
#define FILE_O_READ "r"
#endif
@@ -26,7 +26,7 @@
// ESP32 version
#include "LittleFS.h"
#define FSCom LittleFS
#define FSBegin() FSCom.begin(true)
#define FSBegin() FSCom.begin(true) // format on failure
#define FILE_O_WRITE "w"
#define FILE_O_READ "r"
#endif
@@ -35,13 +35,13 @@
// NRF52 version
#include "InternalFileSystem.h"
#define FSCom InternalFS
#define FSBegin() FSCom.begin()
#define FSBegin() FSCom.begin() // InternalFS formats on failure
using namespace Adafruit_LittleFS_Namespace;
#endif
void fsInit();
bool copyFile(const char* from, const char* to);
bool renameFile(const char* pathFrom, const char* pathTo);
void listDir(const char * dirname, uint8_t levels, boolean del);
void rmDir(const char * dirname);
bool copyFile(const char *from, const char *to);
bool renameFile(const char *pathFrom, const char *pathTo);
void listDir(const char *dirname, uint8_t levels, boolean del);
void rmDir(const char *dirname);
void setupSDCard();

View File

@@ -20,15 +20,15 @@ class GPSStatus : public Status
bool hasLock = false; // default to false, until we complete our first read
bool isConnected = false; // Do we have a GPS we are talking to
bool isPowerSaving = false; //Are we in power saving state
bool isPowerSaving = false; // Are we in power saving state
Position p = Position_init_default;
meshtastic_Position p = meshtastic_Position_init_default;
public:
GPSStatus() { statusType = STATUS_TYPE_GPS; }
// preferred method
GPSStatus(bool hasLock, bool isConnected, bool isPowerSaving, const Position &pos) : Status()
GPSStatus(bool hasLock, bool isConnected, bool isPowerSaving, const meshtastic_Position &pos) : Status()
{
this->hasLock = hasLock;
this->isConnected = isConnected;
@@ -47,7 +47,7 @@ class GPSStatus : public Status
bool getIsConnected() const { return isConnected; }
bool getIsPowerSaving() const { return isPowerSaving;}
bool getIsPowerSaving() const { return isPowerSaving; }
int32_t getLatitude() const
{
@@ -55,7 +55,7 @@ class GPSStatus : public Status
#ifdef GPS_EXTRAVERBOSE
LOG_WARN("Using fixed latitude\n");
#endif
NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
meshtastic_NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
return node->position.latitude_i;
} else {
return p.latitude_i;
@@ -68,7 +68,7 @@ class GPSStatus : public Status
#ifdef GPS_EXTRAVERBOSE
LOG_WARN("Using fixed longitude\n");
#endif
NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
meshtastic_NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
return node->position.longitude_i;
} else {
return p.longitude_i;
@@ -81,29 +81,38 @@ class GPSStatus : public Status
#ifdef GPS_EXTRAVERBOSE
LOG_WARN("Using fixed altitude\n");
#endif
NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
meshtastic_NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
return node->position.altitude;
} else {
return p.altitude;
}
}
uint32_t getDOP() const { return p.PDOP; }
uint32_t getDOP() const
{
return p.PDOP;
}
uint32_t getHeading() const { return p.ground_track; }
uint32_t getHeading() const
{
return p.ground_track;
}
uint32_t getNumSatellites() const { return p.sats_in_view; }
uint32_t getNumSatellites() const
{
return p.sats_in_view;
}
bool matches(const GPSStatus *newStatus) const
{
#ifdef GPS_EXTRAVERBOSE
LOG_DEBUG("GPSStatus.match() new pos@%x to old pos@%x\n", newStatus->p.pos_timestamp, p.pos_timestamp);
#endif
return (newStatus->hasLock != hasLock || newStatus->isConnected != isConnected || newStatus->isPowerSaving !=isPowerSaving ||
newStatus->p.latitude_i != p.latitude_i || newStatus->p.longitude_i != p.longitude_i ||
newStatus->p.altitude != p.altitude || newStatus->p.altitude_hae != p.altitude_hae ||
newStatus->p.PDOP != p.PDOP || newStatus->p.ground_track != p.ground_track ||
newStatus->p.ground_speed != p.ground_speed ||
return (newStatus->hasLock != hasLock || newStatus->isConnected != isConnected ||
newStatus->isPowerSaving != isPowerSaving || newStatus->p.latitude_i != p.latitude_i ||
newStatus->p.longitude_i != p.longitude_i || newStatus->p.altitude != p.altitude ||
newStatus->p.altitude_hae != p.altitude_hae || newStatus->p.PDOP != p.PDOP ||
newStatus->p.ground_track != p.ground_track || newStatus->p.ground_speed != p.ground_speed ||
newStatus->p.sats_in_view != p.sats_in_view);
}

View File

@@ -1,83 +1,68 @@
#pragma once
#include <Arduino.h>
#include "Status.h"
#include "configuration.h"
#include <Arduino.h>
namespace meshtastic {
namespace meshtastic
{
/// Describes the state of the NodeDB system.
class NodeStatus : public Status
/// Describes the state of the NodeDB system.
class NodeStatus : public Status
{
private:
CallbackObserver<NodeStatus, const NodeStatus *> statusObserver =
CallbackObserver<NodeStatus, const NodeStatus *>(this, &NodeStatus::updateStatus);
uint8_t numOnline = 0;
uint8_t numTotal = 0;
uint8_t lastNumTotal = 0;
public:
bool forceUpdate = false;
NodeStatus() { statusType = STATUS_TYPE_NODE; }
NodeStatus(uint8_t numOnline, uint8_t numTotal, bool forceUpdate = false) : Status()
{
this->forceUpdate = forceUpdate;
this->numOnline = numOnline;
this->numTotal = numTotal;
}
NodeStatus(const NodeStatus &);
NodeStatus &operator=(const NodeStatus &);
private:
CallbackObserver<NodeStatus, const NodeStatus *> statusObserver = CallbackObserver<NodeStatus, const NodeStatus *>(this, &NodeStatus::updateStatus);
void observe(Observable<const NodeStatus *> *source) { statusObserver.observe(source); }
uint8_t numOnline = 0;
uint8_t numTotal = 0;
uint8_t getNumOnline() const { return numOnline; }
uint8_t lastNumTotal = 0;
uint8_t getNumTotal() const { return numTotal; }
public:
bool forceUpdate = false;
uint8_t getLastNumTotal() const { return lastNumTotal; }
NodeStatus() {
statusType = STATUS_TYPE_NODE;
}
NodeStatus( uint8_t numOnline, uint8_t numTotal, bool forceUpdate = false ) : Status()
bool matches(const NodeStatus *newStatus) const
{
return (newStatus->getNumOnline() != numOnline || newStatus->getNumTotal() != numTotal);
}
int updateStatus(const NodeStatus *newStatus)
{
// Only update the status if values have actually changed
lastNumTotal = numTotal;
bool isDirty;
{
this->forceUpdate = forceUpdate;
this->numOnline = numOnline;
this->numTotal = numTotal;
isDirty = matches(newStatus);
initialized = true;
numOnline = newStatus->getNumOnline();
numTotal = newStatus->getNumTotal();
}
NodeStatus(const NodeStatus &);
NodeStatus &operator=(const NodeStatus &);
void observe(Observable<const NodeStatus *> *source)
{
statusObserver.observe(source);
if (isDirty || newStatus->forceUpdate) {
LOG_DEBUG("Node status update: %d online, %d total\n", numOnline, numTotal);
onNewStatus.notifyObservers(this);
}
return 0;
}
};
uint8_t getNumOnline() const
{
return numOnline;
}
uint8_t getNumTotal() const
{
return numTotal;
}
uint8_t getLastNumTotal() const
{
return lastNumTotal;
}
bool matches(const NodeStatus *newStatus) const
{
return (
newStatus->getNumOnline() != numOnline ||
newStatus->getNumTotal() != numTotal
);
}
int updateStatus(const NodeStatus *newStatus) {
// Only update the status if values have actually changed
lastNumTotal = numTotal;
bool isDirty;
{
isDirty = matches(newStatus);
initialized = true;
numOnline = newStatus->getNumOnline();
numTotal = newStatus->getNumTotal();
}
if(isDirty || newStatus->forceUpdate) {
LOG_DEBUG("Node status update: %d online, %d total\n", numOnline, numTotal);
onNewStatus.notifyObservers(this);
}
return 0;
}
};
}
} // namespace meshtastic
extern meshtastic::NodeStatus *nodeStatus;

View File

@@ -1,5 +1,5 @@
#include "configuration.h"
#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)

View File

@@ -1,3 +1,2 @@
#include "configuration.h"
#include "Observer.h"
#include "configuration.h"

View File

@@ -1,7 +1,6 @@
#pragma once
#include <Arduino.h>
#include <assert.h>
#include <list>
template <class T> class Observable;
@@ -11,7 +10,7 @@ template <class T> class Observable;
*/
template <class T> class Observer
{
std::list<Observable<T> *> observed;
std::list<Observable<T> *> observed;
public:
virtual ~Observer();
@@ -88,7 +87,7 @@ template <class T> class Observable
template <class T> Observer<T>::~Observer()
{
for (typename std::list<Observable<T> *>::const_iterator iterator = observed.begin(); iterator != observed.end();
++iterator) {
++iterator) {
(*iterator)->removeObserver(this);
}
observed.clear();

View File

@@ -1,16 +1,22 @@
#include "power.h"
#include "NodeDB.h"
#include "PowerFSM.h"
#include "buzz/buzz.h"
#include "configuration.h"
#include "main.h"
#include "sleep.h"
#include "utils.h"
#include "buzz/buzz.h"
#ifdef DEBUG_HEAP_MQTT
#include "mqtt/MQTT.h"
#include "target_specific.h"
#include <WiFi.h>
#endif
#ifdef HAS_PMU
#include "XPowersLibInterface.hpp"
#include "XPowersAXP2101.tpp"
#include "XPowersAXP192.tpp"
#include "XPowersAXP2101.tpp"
#include "XPowersLibInterface.hpp"
XPowersLibInterface *PMU = NULL;
#else
// Copy of the base class defined in axp20x.h.
@@ -108,20 +114,20 @@ class AnalogBatteryLevel : public HasBatteryLevel
#ifdef BATTERY_PIN
// Override variant or default ADC_MULTIPLIER if we have the override pref
float operativeAdcMultiplier = config.power.adc_multiplier_override > 0
? config.power.adc_multiplier_override
: ADC_MULTIPLIER;
float operativeAdcMultiplier =
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) {
last_read_time_ms = millis();
//Set the number of samples, it has an effect of increasing sensitivity, especially in complex electromagnetic environment.
// Set the number of samples, it has an effect of increasing sensitivity, especially in complex electromagnetic
// environment.
uint32_t raw = 0;
for(uint32_t i=0; i<BATTERY_SENSE_SAMPLES; i++){
for (uint32_t i = 0; i < BATTERY_SENSE_SAMPLES; i++) {
raw += analogRead(BATTERY_PIN);
}
raw = raw/BATTERY_SENSE_SAMPLES;
raw = raw / BATTERY_SENSE_SAMPLES;
float scaled;
#ifndef VBAT_RAW_TO_SCALED
@@ -143,15 +149,24 @@ class AnalogBatteryLevel : public HasBatteryLevel
/**
* return true if there is a battery installed in this unit
*/
virtual bool isBatteryConnect() override { return getBatteryPercent() != -1; }
virtual bool isBatteryConnect() override
{
return getBatteryPercent() != -1;
}
/// If we see a battery voltage higher than physics allows - assume charger is pumping
/// in power
virtual bool isVbusIn() override { return getBattVoltage() > chargingVolt; }
virtual bool isVbusIn() override
{
return getBattVoltage() > chargingVolt;
}
/// Assume charging if we have a battery and external power is connected.
/// we can't be smart enough to say 'full'?
virtual bool isCharging() override { return isBatteryConnect() && isVbusIn(); }
virtual bool isCharging() override
{
return isBatteryConnect() && isVbusIn();
}
private:
/// If we see a battery voltage higher than physics allows - assume charger is pumping
@@ -159,16 +174,16 @@ class AnalogBatteryLevel : public HasBatteryLevel
#ifndef BAT_FULLVOLT
#define BAT_FULLVOLT 4200
#endif
#endif
#ifndef BAT_EMPTYVOLT
#define BAT_EMPTYVOLT 3270
#endif
#endif
#ifndef BAT_CHARGINGVOLT
#define BAT_CHARGINGVOLT 4210
#endif
#endif
#ifndef BAT_NOBATVOLT
#define BAT_NOBATVOLT 2230
#endif
#endif
/// For heltecs with no battery connected, the measured voltage is 2204, so raising to 2230 from 2100
const float fullVolt = BAT_FULLVOLT, emptyVolt = BAT_EMPTYVOLT, chargingVolt = BAT_CHARGINGVOLT, noBatVolt = BAT_NOBATVOLT;
@@ -238,12 +253,12 @@ void Power::shutdown()
{
screen->setOn(false);
#if defined(USE_EINK) && defined(PIN_EINK_EN)
digitalWrite(PIN_EINK_EN, LOW); //power off backlight first
digitalWrite(PIN_EINK_EN, LOW); // power off backlight first
#endif
#ifdef HAS_PMU
LOG_INFO("Shutting down\n");
if(PMU) {
if (PMU) {
PMU->setChargingLedMode(XPOWERS_CHG_LED_OFF);
PMU->shutdown();
}
@@ -290,17 +305,37 @@ void Power::readPowerStatus()
if (lastheap != ESP.getFreeHeap()) {
LOG_DEBUG("Threads running:");
int running = 0;
for(int i = 0; i < MAX_THREADS; i++){
for (int i = 0; i < MAX_THREADS; i++) {
auto thread = concurrency::mainController.get(i);
if((thread != nullptr) && (thread->enabled)) {
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", ESP.getFreeHeap(), ESP.getHeapSize(), ESP.getFreeHeap() - lastheap, running, concurrency::mainController.size(false));
LOG_DEBUG("Heap status: %d/%d bytes free (%d), running %d/%d threads\n", ESP.getFreeHeap(), ESP.getHeapSize(),
ESP.getFreeHeap() - lastheap, running, concurrency::mainController.size(false));
lastheap = ESP.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]);
auto newHeap = ESP.getFreeHeap();
std::string heapTopic = "msh/2/heap/" + std::string(mac);
std::string heapString = std::to_string(newHeap);
mqtt->pubSub.publish(heapTopic.c_str(), heapString.c_str(), false);
// auto fragHeap = ESP.getHeapFragmentation();
auto wifiRSSI = WiFi.RSSI();
heapTopic = "msh/2/wifi/" + std::string(mac);
std::string wifiString = std::to_string(wifiRSSI);
mqtt->pubSub.publish(heapTopic.c_str(), wifiString.c_str(), false);
}
#endif
#endif
// If we have a battery at all and it is less than 10% full, force deep sleep if we have more than 3 low readings in a row
@@ -312,7 +347,7 @@ void Power::readPowerStatus()
LOG_DEBUG("Warning RAK4631 Low voltage counter: %d/10\n", low_voltage_counter);
if (low_voltage_counter > 10) {
// We can't trigger deep sleep on NRF52, it's freezing the board
//powerFSM.trigger(EVENT_LOW_BATTERY);
// powerFSM.trigger(EVENT_LOW_BATTERY);
LOG_DEBUG("Low voltage detected, but not triggering deep sleep\n");
}
} else {
@@ -338,11 +373,11 @@ int32_t Power::runOnce()
#ifdef HAS_PMU
// WE no longer use the IRQ line to wake the CPU (due to false wakes from sleep), but we do poll
// the IRQ status by reading the registers over I2C
if(PMU) {
if (PMU) {
PMU->getIrqStatus();
if(PMU->isVbusRemoveIrq()){
if (PMU->isVbusRemoveIrq()) {
LOG_INFO("USB unplugged\n");
powerFSM.trigger(EVENT_POWER_DISCONNECTED);
}
@@ -388,24 +423,24 @@ int32_t Power::runOnce()
share the same i2c bus, instead use ssd1306 sleep mode DCDC2 -> unused DCDC3 0.7-3.5V @ 700mA max -> ESP32 (keep this on!) LDO1
30mA -> charges GPS backup battery // charges the tiny J13 battery by the GPS to power the GPS ram (for a couple of days), can
not be turned off LDO2 200mA -> LORA LDO3 200mA -> GPS
*
*
*/
bool Power::axpChipInit()
{
#ifdef HAS_PMU
TwoWire * w = NULL;
TwoWire *w = NULL;
// Use macro to distinguish which wire is used by PMU
#ifdef PMU_USE_WIRE1
w = &Wire1;
w = &Wire1;
#else
w = &Wire;
w = &Wire;
#endif
/**
* It is not necessary to specify the wire pin,
* It is not necessary to specify the wire pin,
* just input the wire, because the wire has been initialized in main.cpp
*/
if (!PMU) {
@@ -431,11 +466,11 @@ bool Power::axpChipInit()
}
if (!PMU) {
/*
* In XPowersLib, if the XPowersAXPxxx object is released, Wire.end() will be called at the same time.
* In order not to affect other devices, if the initialization of the PMU fails, Wire needs to be re-initialized once,
* if there are multiple devices sharing the bus.
* * */
/*
* In XPowersLib, if the XPowersAXPxxx object is released, Wire.end() will be called at the same time.
* In order not to affect other devices, if the initialization of the PMU fails, Wire needs to be re-initialized once,
* if there are multiple devices sharing the bus.
* * */
#ifndef PMU_USE_WIRE1
w->begin(I2C_SDA, I2C_SCL);
#endif
@@ -445,48 +480,45 @@ bool Power::axpChipInit()
batteryLevel = PMU;
if (PMU->getChipModel() == XPOWERS_AXP192) {
// lora radio power channel
PMU->setPowerChannelVoltage(XPOWERS_LDO2, 3300);
PMU->enablePowerOutput(XPOWERS_LDO2);
// oled module power channel,
// disable it will cause abnormal communication between boot and AXP power supply,
// disable it will cause abnormal communication between boot and AXP power supply,
// do not turn it off
PMU->setPowerChannelVoltage(XPOWERS_DCDC1, 3300);
// enable oled power
PMU->enablePowerOutput(XPOWERS_DCDC1);
// gnss module power channel - now turned on in setGpsPower
PMU->setPowerChannelVoltage(XPOWERS_LDO3, 3300);
// PMU->enablePowerOutput(XPOWERS_LDO3);
//protected oled power source
// protected oled power source
PMU->setProtectedChannel(XPOWERS_DCDC1);
//protected esp32 power source
// protected esp32 power source
PMU->setProtectedChannel(XPOWERS_DCDC3);
//disable not use channel
// disable not use channel
PMU->disablePowerOutput(XPOWERS_DCDC2);
//disable all axp chip interrupt
// disable all axp chip interrupt
PMU->disableIRQ(XPOWERS_AXP192_ALL_IRQ);
// Set constant current charging current
PMU->setChargerConstantCurr(XPOWERS_AXP192_CHG_CUR_450MA);
//Set up the charging voltage
// Set up the charging voltage
PMU->setChargeTargetVoltage(XPOWERS_AXP192_CHG_VOL_4V2);
} else if (PMU->getChipModel() == XPOWERS_AXP2101) {
// t-beam s3 core
// t-beam s3 core
/**
* gnss module power channel
* gnss module power channel
* The default ALDO4 is off, you need to turn on the GNSS power first, otherwise it will be invalid during initialization
*/
PMU->setPowerChannelVoltage(XPOWERS_ALDO4, 3300);
@@ -496,51 +528,50 @@ bool Power::axpChipInit()
PMU->setPowerChannelVoltage(XPOWERS_ALDO3, 3300);
PMU->enablePowerOutput(XPOWERS_ALDO3);
// m.2 interface
// m.2 interface
PMU->setPowerChannelVoltage(XPOWERS_DCDC3, 3300);
PMU->enablePowerOutput(XPOWERS_DCDC3);
/**
* ALDO2 cannot be turned off.
* It is a necessary condition for sensor communication.
* It must be turned on to properly access the sensor and screen
* It is also responsible for the power supply of PCF8563
*/
* ALDO2 cannot be turned off.
* It is a necessary condition for sensor communication.
* It must be turned on to properly access the sensor and screen
* It is also responsible for the power supply of PCF8563
*/
PMU->setPowerChannelVoltage(XPOWERS_ALDO2, 3300);
PMU->enablePowerOutput(XPOWERS_ALDO2);
// 6-axis , magnetometer ,bme280 , oled screen power channel
// 6-axis , magnetometer ,bme280 , oled screen power channel
PMU->setPowerChannelVoltage(XPOWERS_ALDO1, 3300);
PMU->enablePowerOutput(XPOWERS_ALDO1);
// sdcard power channle
// sdcard power channle
PMU->setPowerChannelVoltage(XPOWERS_BLDO1, 3300);
PMU->enablePowerOutput(XPOWERS_BLDO1);
// PMU->setPowerChannelVoltage(XPOWERS_DCDC4, 3300);
// PMU->enablePowerOutput(XPOWERS_DCDC4);
//not use channel
PMU->disablePowerOutput(XPOWERS_DCDC2); //not elicited
PMU->disablePowerOutput(XPOWERS_DCDC5); //not elicited
PMU->disablePowerOutput(XPOWERS_DLDO1); //Invalid power channel, it does not exist
PMU->disablePowerOutput(XPOWERS_DLDO2); //Invalid power channel, it does not exist
// not use channel
PMU->disablePowerOutput(XPOWERS_DCDC2); // not elicited
PMU->disablePowerOutput(XPOWERS_DCDC5); // not elicited
PMU->disablePowerOutput(XPOWERS_DLDO1); // Invalid power channel, it does not exist
PMU->disablePowerOutput(XPOWERS_DLDO2); // Invalid power channel, it does not exist
PMU->disablePowerOutput(XPOWERS_VBACKUP);
//disable all axp chip interrupt
// disable all axp chip interrupt
PMU->disableIRQ(XPOWERS_AXP2101_ALL_IRQ);
//Set the constant current charging current of AXP2101, temporarily use 500mA by default
// Set the constant current charging current of AXP2101, temporarily use 500mA by default
PMU->setChargerConstantCurr(XPOWERS_AXP2101_CHG_CUR_500MA);
//Set up the charging voltage
// Set up the charging voltage
PMU->setChargeTargetVoltage(XPOWERS_AXP2101_CHG_VOL_4V2);
}
PMU->clearIrqStatus();
// TBeam1.1 /T-Beam S3-Core has no external TS detection,
// TBeam1.1 /T-Beam S3-Core has no external TS detection,
// it needs to be disabled, otherwise it will cause abnormal charging
PMU->disableTSPinMeasure();
@@ -550,40 +581,52 @@ bool Power::axpChipInit()
LOG_DEBUG("=======================================================================\n");
if (PMU->isChannelAvailable(XPOWERS_DCDC1)) {
LOG_DEBUG("DC1 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC1) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC1));
LOG_DEBUG("DC1 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC1) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_DCDC1));
}
if (PMU->isChannelAvailable(XPOWERS_DCDC2)) {
LOG_DEBUG("DC2 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC2));
LOG_DEBUG("DC2 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC2) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_DCDC2));
}
if (PMU->isChannelAvailable(XPOWERS_DCDC3)) {
LOG_DEBUG("DC3 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC3) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC3));
LOG_DEBUG("DC3 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC3) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_DCDC3));
}
if (PMU->isChannelAvailable(XPOWERS_DCDC4)) {
LOG_DEBUG("DC4 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC4) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC4));
LOG_DEBUG("DC4 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC4) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_DCDC4));
}
if (PMU->isChannelAvailable(XPOWERS_LDO2)) {
LOG_DEBUG("LDO2 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_LDO2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_LDO2));
LOG_DEBUG("LDO2 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_LDO2) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_LDO2));
}
if (PMU->isChannelAvailable(XPOWERS_LDO3)) {
LOG_DEBUG("LDO3 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_LDO3) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_LDO3));
LOG_DEBUG("LDO3 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_LDO3) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_LDO3));
}
if (PMU->isChannelAvailable(XPOWERS_ALDO1)) {
LOG_DEBUG("ALDO1: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO1) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO1));
LOG_DEBUG("ALDO1: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO1) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_ALDO1));
}
if (PMU->isChannelAvailable(XPOWERS_ALDO2)) {
LOG_DEBUG("ALDO2: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO2));
LOG_DEBUG("ALDO2: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO2) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_ALDO2));
}
if (PMU->isChannelAvailable(XPOWERS_ALDO3)) {
LOG_DEBUG("ALDO3: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO3) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO3));
LOG_DEBUG("ALDO3: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO3) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_ALDO3));
}
if (PMU->isChannelAvailable(XPOWERS_ALDO4)) {
LOG_DEBUG("ALDO4: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO4) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO4));
LOG_DEBUG("ALDO4: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO4) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_ALDO4));
}
if (PMU->isChannelAvailable(XPOWERS_BLDO1)) {
LOG_DEBUG("BLDO1: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_BLDO1) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_BLDO1));
LOG_DEBUG("BLDO1: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_BLDO1) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_BLDO1));
}
if (PMU->isChannelAvailable(XPOWERS_BLDO2)) {
LOG_DEBUG("BLDO2: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_BLDO2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_BLDO2));
LOG_DEBUG("BLDO2: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_BLDO2) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_BLDO2));
}
LOG_DEBUG("=======================================================================\n");
@@ -597,30 +640,29 @@ bool Power::axpChipInit()
PMU->setSysPowerDownVoltage(2600);
#endif
#ifdef PMU_IRQ
uint64_t pmuIrqMask = 0;
uint64_t pmuIrqMask = 0;
if (PMU->getChipModel() == XPOWERS_AXP192) {
pmuIrqMask = XPOWERS_AXP192_VBUS_INSERT_IRQ | XPOWERS_AXP192_BAT_INSERT_IRQ | XPOWERS_AXP192_PKEY_SHORT_IRQ;
} else if (PMU->getChipModel() == XPOWERS_AXP2101) {
pmuIrqMask = XPOWERS_AXP2101_VBUS_INSERT_IRQ | XPOWERS_AXP2101_BAT_INSERT_IRQ | XPOWERS_AXP2101_PKEY_SHORT_IRQ;
}
if (PMU->getChipModel() == XPOWERS_AXP192) {
pmuIrqMask = XPOWERS_AXP192_VBUS_INSERT_IRQ | XPOWERS_AXP192_BAT_INSERT_IRQ | XPOWERS_AXP192_PKEY_SHORT_IRQ;
} else if (PMU->getChipModel() == XPOWERS_AXP2101) {
pmuIrqMask = XPOWERS_AXP2101_VBUS_INSERT_IRQ | XPOWERS_AXP2101_BAT_INSERT_IRQ | XPOWERS_AXP2101_PKEY_SHORT_IRQ;
}
pinMode(PMU_IRQ, INPUT);
attachInterrupt(
PMU_IRQ, [] { pmu_irq = true; }, FALLING);
pinMode(PMU_IRQ, INPUT);
attachInterrupt(
PMU_IRQ, [] { pmu_irq = true; }, FALLING);
// we do not look for AXPXXX_CHARGING_FINISHED_IRQ & AXPXXX_CHARGING_IRQ because it occurs repeatedly while there is
// no battery also it could cause inadvertent waking from light sleep just because the battery filled
// we don't look for AXPXXX_BATT_REMOVED_IRQ because it occurs repeatedly while no battery installed
// we don't look at AXPXXX_VBUS_REMOVED_IRQ because we don't have anything hooked to vbus
PMU->enableIRQ(pmuIrqMask);
// we do not look for AXPXXX_CHARGING_FINISHED_IRQ & AXPXXX_CHARGING_IRQ because it occurs repeatedly while there is
// no battery also it could cause inadvertent waking from light sleep just because the battery filled
// we don't look for AXPXXX_BATT_REMOVED_IRQ because it occurs repeatedly while no battery installed
// we don't look at AXPXXX_VBUS_REMOVED_IRQ because we don't have anything hooked to vbus
PMU->enableIRQ(pmuIrqMask);
PMU->clearIrqStatus();
PMU->clearIrqStatus();
#endif /*PMU_IRQ*/
readPowerStatus();
readPowerStatus();
pmu_found = true;

View File

@@ -11,12 +11,12 @@
/// 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)
return true;
#endif
// 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)
return true;
#endif
bool isRouter = (config.device.role == Config_DeviceConfig_Role_ROUTER ? 1 : 0);
bool isRouter = (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER ? 1 : 0);
// If we are not a router and we already have AC power go to POWER state after init, otherwise go to ON
// We assume routers might be powered all the time, but from a low current (solar) source
@@ -78,8 +78,8 @@ 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
wakeCause2 = doLightSleep(1); // leave led on for 1ms
setLed(true); // briefly turn on led
wakeCause2 = doLightSleep(100); // leave led on for 1ms
secsSlept += sleepTime;
// LOG_INFO("sleeping, flash led!\n");
@@ -199,7 +199,8 @@ static void onEnter()
uint32_t now = millis();
if ((now - lastPingMs) > 30 * 1000) { // if more than a minute since our last press, ask node we are looking at to update their state
if ((now - lastPingMs) >
30 * 1000) { // if more than a minute since our last press, ask node we are looking at to update their state
if (displayedNodeNum)
service.sendNetworkPing(displayedNodeNum, true); // Refresh the currently displayed node
lastPingMs = now;
@@ -237,7 +238,7 @@ Fsm powerFSM(&stateBOOT);
void PowerFSM_setup()
{
bool isRouter = (config.device.role == Config_DeviceConfig_Role_ROUTER ? 1 : 0);
bool isRouter = (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER ? 1 : 0);
bool hasPower = isPowered();
LOG_INFO("PowerFSM init, USB power=%d\n", hasPower ? 1 : 0);
@@ -249,7 +250,8 @@ void PowerFSM_setup()
// We need this transition, because we might not transition if we were waiting to enter light-sleep, because when we wake from
// light sleep we _always_ transition to NB or dark and
powerFSM.add_transition(&stateLS, isRouter ? &stateNB : &stateDARK, EVENT_PACKET_FOR_PHONE, NULL, "Received packet, exiting light sleep");
powerFSM.add_transition(&stateLS, isRouter ? &stateNB : &stateDARK, EVENT_PACKET_FOR_PHONE, NULL,
"Received packet, exiting light sleep");
powerFSM.add_transition(&stateNB, &stateNB, EVENT_PACKET_FOR_PHONE, NULL, "Received packet, resetting win wake");
// Handle press events - note: we ignore button presses when in API mode
@@ -258,7 +260,8 @@ void PowerFSM_setup()
powerFSM.add_transition(&stateDARK, &stateON, EVENT_PRESS, NULL, "Press");
powerFSM.add_transition(&statePOWER, &statePOWER, EVENT_PRESS, screenPress, "Press");
powerFSM.add_transition(&stateON, &stateON, EVENT_PRESS, screenPress, "Press"); // reenter On to restart our timers
powerFSM.add_transition(&stateSERIAL, &stateSERIAL, EVENT_PRESS, screenPress, "Press"); // Allow button to work while in serial API
powerFSM.add_transition(&stateSERIAL, &stateSERIAL, EVENT_PRESS, screenPress,
"Press"); // Allow button to work while in serial API
// Handle critically low power battery by forcing deep sleep
powerFSM.add_transition(&stateBOOT, &stateSDS, EVENT_LOW_BATTERY, NULL, "LowBat");
@@ -324,7 +327,9 @@ void PowerFSM_setup()
powerFSM.add_transition(&stateDARK, &stateDARK, EVENT_CONTACT_FROM_PHONE, NULL, "Contact from phone");
powerFSM.add_timed_transition(&stateON, &stateDARK, getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs), NULL, "Screen-on timeout");
powerFSM.add_timed_transition(&stateON, &stateDARK,
getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs), NULL,
"Screen-on timeout");
#ifdef ARCH_ESP32
State *lowPowerState = &stateLS;
@@ -332,14 +337,18 @@ void PowerFSM_setup()
// See: https://github.com/meshtastic/firmware/issues/1071
if (isRouter || config.power.is_power_saving) {
powerFSM.add_timed_transition(&stateNB, &stateLS, getConfiguredOrDefaultMs(config.power.min_wake_secs, default_min_wake_secs), NULL, "Min wake timeout");
powerFSM.add_timed_transition(&stateDARK, &stateLS, getConfiguredOrDefaultMs(config.power.wait_bluetooth_secs, default_wait_bluetooth_secs), NULL, "Bluetooth timeout");
powerFSM.add_timed_transition(&stateNB, &stateLS,
getConfiguredOrDefaultMs(config.power.min_wake_secs, default_min_wake_secs), NULL,
"Min wake timeout");
powerFSM.add_timed_transition(&stateDARK, &stateLS,
getConfiguredOrDefaultMs(config.power.wait_bluetooth_secs, default_wait_bluetooth_secs),
NULL, "Bluetooth timeout");
}
if (config.power.sds_secs != UINT32_MAX)
powerFSM.add_timed_transition(lowPowerState, &stateSDS, getConfiguredOrDefaultMs(config.power.sds_secs), NULL, "mesh timeout");
powerFSM.add_timed_transition(lowPowerState, &stateSDS, getConfiguredOrDefaultMs(config.power.sds_secs), NULL,
"mesh timeout");
#endif
powerFSM.run_machine(); // run one interation of the state machine, so we run our on enter tasks for the initial DARK state
}

View File

@@ -19,8 +19,8 @@
#define EVENT_POWER_CONNECTED 13
#define EVENT_POWER_DISCONNECTED 14
#define EVENT_FIRMWARE_UPDATE 15 // We just received a new firmware update packet from the phone
#define EVENT_SHUTDOWN 16 //force a full shutdown now (not just sleep)
#define EVENT_INPUT 17 // input broker wants something, we need to wake up and enable screen
#define EVENT_SHUTDOWN 16 // force a full shutdown now (not just sleep)
#define EVENT_INPUT 17 // input broker wants something, we need to wake up and enable screen
extern Fsm powerFSM;
extern State statePOWER, stateSERIAL;

View File

@@ -26,9 +26,10 @@ class PowerFSMThread : public OSThread
if (powerStatus->getHasUSB()) {
timeLastPowered = millis();
} else if (config.power.on_battery_shutdown_after_secs > 0 &&
config.power.on_battery_shutdown_after_secs != UINT32_MAX &&
millis() > (timeLastPowered + getConfiguredOrDefaultMs(config.power.on_battery_shutdown_after_secs))) { // shutdown after 30 minutes unpowered
} else if (config.power.on_battery_shutdown_after_secs > 0 && config.power.on_battery_shutdown_after_secs != UINT32_MAX &&
millis() > (timeLastPowered +
getConfiguredOrDefaultMs(
config.power.on_battery_shutdown_after_secs))) { // shutdown after 30 minutes unpowered
powerFSM.trigger(EVENT_SHUTDOWN);
}

View File

@@ -2,6 +2,6 @@
#ifdef USE_RF95
#define RF95_RESET LORA_RESET
#define RF95_IRQ LORA_DIO0 // on SX1262 version this is a no connect DIO0
#define RF95_DIO1 LORA_DIO1 // Note: not really used for RF95
#define RF95_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

View File

@@ -1,19 +1,24 @@
#include "configuration.h"
#include "RedirectablePrint.h"
#include "RTC.h"
#include "NodeDB.h"
#include "RTC.h"
#include "concurrency/OSThread.h"
// #include "wifi/WiFiServerAPI.h"
#include "configuration.h"
#include <assert.h>
#include <cstring>
#include <memory>
#include <stdexcept>
#include <sys/time.h>
#include <time.h>
#include <cstring>
/**
* A printer that doesn't go anywhere
*/
NoopPrint noopPrint;
#if HAS_WIFI || HAS_ETHERNET
extern Syslog syslog;
#endif
void RedirectablePrint::setDestination(Print *_dest)
{
assert(_dest);
@@ -27,10 +32,6 @@ size_t RedirectablePrint::write(uint8_t c)
SEGGER_RTT_PutChar(SEGGER_STDOUT_CH, c);
#endif
// FIXME - clean this up, the whole relationship of this class to SerialConsole to TCP/bluetooth debug log output is kinda messed up. But for now, just have this hack to
// optionally send chars to TCP also
//WiFiServerPort::debugOut(c);
if (!config.has_lora || config.device.serial_enabled)
dest->write(c);
@@ -47,7 +48,8 @@ size_t RedirectablePrint::vprintf(const char *format, va_list arg)
size_t len = vsnprintf(printBuf, sizeof(printBuf), format, copy);
va_end(copy);
// If the resulting string is longer than sizeof(printBuf)-1 characters, the remaining characters are still counted for the return value
// If the resulting string is longer than sizeof(printBuf)-1 characters, the remaining characters are still counted for the
// return value
if (len > sizeof(printBuf) - 1) {
len = sizeof(printBuf) - 1;
@@ -100,6 +102,39 @@ size_t RedirectablePrint::log(const char *logLevel, const char *format, ...)
}
}
r += vprintf(format, arg);
#if (HAS_WIFI || HAS_ETHERNET) && !defined(ARCH_PORTDUINO)
// if syslog is in use, collect the log messages and send them to syslog
if (syslog.isEnabled()) {
int ll = 0;
switch (logLevel[0]) {
case 'D':
ll = SYSLOG_DEBUG;
break;
case 'I':
ll = SYSLOG_INFO;
break;
case 'W':
ll = SYSLOG_WARN;
break;
case 'E':
ll = SYSLOG_ERR;
break;
case 'C':
ll = SYSLOG_CRIT;
break;
default:
ll = 0;
}
auto thread = concurrency::OSThread::currentThread;
if (thread) {
syslog.vlogf(ll, thread->ThreadName.c_str(), format, arg);
} else {
syslog.vlogf(ll, format, arg);
}
}
#endif
va_end(arg);
isContinuationMessage = !hasNewline;
@@ -108,3 +143,54 @@ size_t RedirectablePrint::log(const char *logLevel, const char *format, ...)
return r;
}
void RedirectablePrint::hexDump(const char *logLevel, unsigned char *buf, uint16_t len)
{
const char alphabet[17] = "0123456789abcdef";
log(logLevel, " +------------------------------------------------+ +----------------+\n");
log(logLevel, " |.0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .a .b .c .d .e .f | | ASCII |\n");
for (uint16_t i = 0; i < len; i += 16) {
if (i % 128 == 0)
log(logLevel, " +------------------------------------------------+ +----------------+\n");
char s[] = "| | | |\n";
uint8_t ix = 1, iy = 52;
for (uint8_t j = 0; j < 16; j++) {
if (i + j < len) {
uint8_t c = buf[i + j];
s[ix++] = alphabet[(c >> 4) & 0x0F];
s[ix++] = alphabet[c & 0x0F];
ix++;
if (c > 31 && c < 128)
s[iy++] = c;
else
s[iy++] = '.';
}
}
uint8_t index = i / 16;
if (i < 256)
log(logLevel, " ");
log(logLevel, "%02x", index);
log(logLevel, ".");
log(logLevel, s);
}
log(logLevel, " +------------------------------------------------+ +----------------+\n");
}
std::string RedirectablePrint::mt_sprintf(const std::string fmt_str, ...)
{
int n = ((int)fmt_str.size()) * 2; /* Reserve two times as much as the length of the fmt_str */
std::unique_ptr<char[]> formatted;
va_list ap;
while (1) {
formatted.reset(new char[n]); /* Wrap the plain char array into the unique_ptr */
strcpy(&formatted[0], fmt_str.c_str());
va_start(ap, fmt_str);
int final_n = vsnprintf(&formatted[0], n, fmt_str.c_str(), ap);
va_end(ap);
if (final_n < 0 || final_n >= n)
n += abs(final_n - n + 1);
else
break;
}
return std::string(formatted.get());
}

View File

@@ -2,6 +2,7 @@
#include <Print.h>
#include <stdarg.h>
#include <string>
/**
* A Printable that can be switched to squirt its bytes to a different sink.
@@ -29,15 +30,19 @@ class RedirectablePrint : public Print
/**
* Debug logging print message
*
*
* If the provide format string ends with a newline we assume it is the final print of a single
* log message. Otherwise we assume more prints will come before the log message ends. This
* allows you to call logDebug a few times to build up a single log message line if you wish.
*/
size_t log(const char *logLevel, const char *format, ...) __attribute__ ((format (printf, 3, 4)));
size_t log(const char *logLevel, const char *format, ...) __attribute__((format(printf, 3, 4)));
/** like printf but va_list based */
size_t vprintf(const char *format, va_list arg);
void hexDump(const char *logLevel, unsigned char *buf, uint16_t len);
std::string mt_sprintf(const std::string fmt_str, ...);
};
class NoopPrint : public Print

View File

@@ -1,5 +1,5 @@
#include "configuration.h"
#include "SPILock.h"
#include "configuration.h"
#include <Arduino.h>
#include <assert.h>

View File

@@ -20,9 +20,7 @@ void consolePrintf(const char *format, ...)
va_start(arg, format);
console->vprintf(format, arg);
va_end(arg);
#ifdef ARCH_ESP32
console->flush();
#endif
}
SerialConsole::SerialConsole() : StreamAPI(&Port), RedirectablePrint(&Port), concurrency::OSThread("SerialConsole")
@@ -51,6 +49,11 @@ int32_t SerialConsole::runOnce()
return runOncePart();
}
void SerialConsole::flush()
{
Port.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()
{
@@ -72,7 +75,7 @@ bool SerialConsole::handleToRadio(const uint8_t *buf, size_t len)
canWrite = true;
return StreamAPI::handleToRadio(buf, len);
}else{
} else {
return false;
}
}

View File

@@ -26,8 +26,9 @@ class SerialConsole : public StreamAPI, public RedirectablePrint, private concur
virtual int32_t runOnce() override;
protected:
void flush();
protected:
/// Check the current underlying physical link to see if the client is currently connected
virtual bool checkIsConnected() override;
};

View File

@@ -8,65 +8,49 @@
#define STATUS_TYPE_GPS 2
#define STATUS_TYPE_NODE 3
namespace meshtastic
{
// A base class for observable status
class Status
// A base class for observable status
class Status
{
protected:
// Allows us to observe an Observable
CallbackObserver<Status, const Status *> statusObserver =
CallbackObserver<Status, const Status *>(this, &Status::updateStatus);
bool initialized = false;
// Workaround for no typeid support
int statusType = 0;
public:
// Allows us to generate observable events
Observable<const Status *> onNewStatus;
// Enable polymorphism ?
virtual ~Status() = default;
Status()
{
protected:
// Allows us to observe an Observable
CallbackObserver<Status, const Status *> statusObserver = CallbackObserver<Status, const Status *>(this, &Status::updateStatus);
bool initialized = false;
// Workaround for no typeid support
int statusType = 0;
public:
// Allows us to generate observable events
Observable<const Status *> onNewStatus;
// Enable polymorphism ?
virtual ~Status() = default;
Status() {
if (!statusType)
{
statusType = STATUS_TYPE_BASE;
}
if (!statusType) {
statusType = STATUS_TYPE_BASE;
}
}
// Prevent object copy/move
Status(const Status &) = delete;
Status &operator=(const Status &) = delete;
// Prevent object copy/move
Status(const Status &) = delete;
Status &operator=(const Status &) = delete;
// Start observing a source of data
void observe(Observable<const Status *> *source)
{
statusObserver.observe(source);
}
// Start observing a source of data
void observe(Observable<const Status *> *source) { statusObserver.observe(source); }
// Determines whether or not existing data matches the data in another Status instance
bool matches(const Status *otherStatus) const
{
return true;
}
// Determines whether or not existing data matches the data in another Status instance
bool matches(const Status *otherStatus) const { return true; }
bool isInitialized() const
{
return initialized;
}
bool isInitialized() const { return initialized; }
int getStatusType() const
{
return statusType;
}
int getStatusType() const { return statusType; }
// Called when the Observable we're observing generates a new notification
int updateStatus(const Status *newStatus)
{
return 0;
}
};
// Called when the Observable we're observing generates a new notification
int updateStatus(const Status *newStatus) { return 0; }
};
}; // namespace meshtastic

View File

@@ -34,11 +34,13 @@ uint8_t AirTime::currentPeriodIndex()
return ((getSecondsSinceBoot() / SECONDS_PER_PERIOD) % PERIODS_TO_LOG);
}
uint8_t AirTime::getPeriodUtilMinute() {
uint8_t AirTime::getPeriodUtilMinute()
{
return (getSecondsSinceBoot() / 10) % CHANNEL_UTILIZATION_PERIODS;
}
uint8_t AirTime::getPeriodUtilHour() {
uint8_t AirTime::getPeriodUtilHour()
{
return (getSecondsSinceBoot() / 60) % MINUTES_IN_HOUR;
}
@@ -117,22 +119,45 @@ float AirTime::utilizationTXPercent()
return (float(sum) / float(MS_IN_HOUR)) * 100;
}
bool AirTime::isTxAllowedChannelUtil(bool polite)
{
uint8_t percentage = (polite ? polite_channel_util_percent : max_channel_util_percent);
if (channelUtilizationPercent() < percentage) {
return true;
} else {
LOG_WARN("Channel utilization is >%d percent. Skipping this opportunity to send.\n", percentage);
return false;
}
}
bool AirTime::isTxAllowedAirUtil()
{
if (!config.lora.override_duty_cycle && myRegion->dutyCycle < 100) {
if (utilizationTXPercent() < myRegion->dutyCycle * polite_duty_cycle_percent / 100) {
return true;
} else {
LOG_WARN("Tx air utilization is >%f percent. Skipping this opportunity to send.\n",
myRegion->dutyCycle * polite_duty_cycle_percent / 100);
return false;
}
}
return true;
}
// Get the amount of minutes we have to be silent before we can send again
uint8_t AirTime::getSilentMinutes(float txPercent, float dutyCycle)
{
float newTxPercent = txPercent;
for (int8_t i = MINUTES_IN_HOUR-1; i >= 0; --i) {
newTxPercent -= ((float)this->utilizationTX[i] / (MS_IN_MINUTE * MINUTES_IN_HOUR / 100));
if (newTxPercent < dutyCycle)
return MINUTES_IN_HOUR-1-i;
}
uint8_t AirTime::getSilentMinutes(float txPercent, float dutyCycle)
{
float newTxPercent = txPercent;
for (int8_t i = MINUTES_IN_HOUR - 1; i >= 0; --i) {
newTxPercent -= ((float)this->utilizationTX[i] / (MS_IN_MINUTE * MINUTES_IN_HOUR / 100));
if (newTxPercent < dutyCycle)
return MINUTES_IN_HOUR - 1 - i;
}
return MINUTES_IN_HOUR;
return MINUTES_IN_HOUR;
}
AirTime::AirTime() : concurrency::OSThread("AirTime"),airtimes({}) {
}
AirTime::AirTime() : concurrency::OSThread("AirTime"), airtimes({}) {}
int32_t AirTime::runOnce()
{
@@ -188,14 +213,14 @@ int32_t AirTime::runOnce()
// Update channel_utilization every second.
myNodeInfo.air_util_tx = airTime->utilizationTXPercent();
}
/*
LOG_DEBUG("utilPeriodTX %d TX Airtime %3.2f%\n", utilPeriodTX, airTime->utilizationTXPercent());
for (uint32_t i = 0; i < MINUTES_IN_HOUR; i++) {
LOG_DEBUG(
"%d,", this->utilizationTX[i]
);
}
LOG_DEBUG("\n");
*/
/*
LOG_DEBUG("utilPeriodTX %d TX Airtime %3.2f%\n", utilPeriodTX, airTime->utilizationTXPercent());
for (uint32_t i = 0; i < MINUTES_IN_HOUR; i++) {
LOG_DEBUG(
"%d,", this->utilizationTX[i]
);
}
LOG_DEBUG("\n");
*/
return (1000 * 1);
}

View File

@@ -1,5 +1,6 @@
#pragma once
#include "MeshRadio.h"
#include "concurrency/OSThread.h"
#include "configuration.h"
#include <Arduino.h>
@@ -32,7 +33,6 @@
#define MS_IN_MINUTE (SECONDS_IN_MINUTE * 1000)
#define MS_IN_HOUR (MINUTES_IN_HOUR * SECONDS_IN_MINUTE * 1000)
enum reportTypes { TX_LOG, RX_LOG, RX_ALL_LOG };
void logAirtime(reportTypes reportType, uint32_t airtime_ms);
@@ -59,12 +59,17 @@ class AirTime : private concurrency::OSThread
uint32_t getSecondsSinceBoot();
uint32_t *airtimeReport(reportTypes reportType);
uint8_t getSilentMinutes(float txPercent, float dutyCycle);
bool isTxAllowedChannelUtil(bool polite = false);
bool isTxAllowedAirUtil();
private:
bool firstTime = true;
uint8_t lastUtilPeriod = 0;
uint8_t lastUtilPeriodTX = 0;
uint32_t secSinceBoot = 0;
uint8_t max_channel_util_percent = 40;
uint8_t polite_channel_util_percent = 25;
uint8_t polite_duty_cycle_percent = 50; // half of Duty Cycle allowance is ok for metadata
struct airtimeStruct {
uint32_t periodTX[PERIODS_TO_LOG]; // AirTime transmitted

View File

@@ -1,6 +1,6 @@
#include "buzz.h"
#include "configuration.h"
#include "NodeDB.h"
#include "configuration.h"
#if !defined(ARCH_ESP32) && !defined(ARCH_RP2040) && !defined(ARCH_PORTDUINO)
#include "Tone.h"
@@ -11,8 +11,8 @@ extern "C" void delay(uint32_t dwMs);
#endif
struct ToneDuration {
int frequency_khz;
int duration_ms;
int frequency_khz;
int duration_ms;
};
// Some common frequencies.
@@ -30,40 +30,39 @@ struct ToneDuration {
#define NOTE_B3 247
#define NOTE_CS4 277
const int DURATION_1_8 = 125; // 1/8 note
const int DURATION_1_4 = 250; // 1/4 note
const int DURATION_1_8 = 125; // 1/8 note
const int DURATION_1_4 = 250; // 1/4 note
void playTones(const ToneDuration *tone_durations, int size) {
void playTones(const ToneDuration *tone_durations, int size)
{
#ifdef PIN_BUZZER
if (!config.device.buzzer_gpio)
config.device.buzzer_gpio = PIN_BUZZER;
if (!config.device.buzzer_gpio)
config.device.buzzer_gpio = PIN_BUZZER;
#endif
if (config.device.buzzer_gpio) {
for (int i = 0; i < size; i++) {
const auto &tone_duration = tone_durations[i];
tone(config.device.buzzer_gpio, tone_duration.frequency_khz, tone_duration.duration_ms);
// to distinguish the notes, set a minimum time between them.
delay(1.3 * tone_duration.duration_ms);
if (config.device.buzzer_gpio) {
for (int i = 0; i < size; i++) {
const auto &tone_duration = tone_durations[i];
tone(config.device.buzzer_gpio, tone_duration.frequency_khz, tone_duration.duration_ms);
// to distinguish the notes, set a minimum time between them.
delay(1.3 * tone_duration.duration_ms);
}
}
}
}
void playBeep() {
ToneDuration melody[] = {{NOTE_B3, DURATION_1_4}};
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
void playBeep()
{
ToneDuration melody[] = {{NOTE_B3, DURATION_1_4}};
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
}
void playStartMelody() {
ToneDuration melody[] = {{NOTE_FS3, DURATION_1_8},
{NOTE_AS3, DURATION_1_8},
{NOTE_CS4, DURATION_1_4}};
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
void playStartMelody()
{
ToneDuration melody[] = {{NOTE_FS3, DURATION_1_8}, {NOTE_AS3, DURATION_1_8}, {NOTE_CS4, DURATION_1_4}};
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
}
void playShutdownMelody() {
ToneDuration melody[] = {{NOTE_CS4, DURATION_1_8},
{NOTE_AS3, DURATION_1_8},
{NOTE_FS3, DURATION_1_4}};
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
void playShutdownMelody()
{
ToneDuration melody[] = {{NOTE_CS4, DURATION_1_8}, {NOTE_AS3, DURATION_1_8}, {NOTE_FS3, DURATION_1_4}};
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
}

View File

@@ -4,15 +4,15 @@
*/
enum class Cmd {
INVALID,
SET_ON,
SET_OFF,
ON_PRESS,
START_BLUETOOTH_PIN_SCREEN,
START_FIRMWARE_UPDATE_SCREEN,
STOP_BLUETOOTH_PIN_SCREEN,
STOP_BOOT_SCREEN,
PRINT,
START_SHUTDOWN_SCREEN,
START_REBOOT_SCREEN,
INVALID,
SET_ON,
SET_OFF,
ON_PRESS,
START_BLUETOOTH_PIN_SCREEN,
START_FIRMWARE_UPDATE_SCREEN,
STOP_BLUETOOTH_PIN_SCREEN,
STOP_BOOT_SCREEN,
PRINT,
START_SHUTDOWN_SCREEN,
START_REBOOT_SCREEN,
};

View File

@@ -1,5 +1,5 @@
#include "configuration.h"
#include "concurrency/BinarySemaphoreFreeRTOS.h"
#include "configuration.h"
#include <assert.h>
#ifdef HAS_FREE_RTOS

View File

@@ -1,18 +1,14 @@
#include "configuration.h"
#include "concurrency/BinarySemaphorePosix.h"
#include "configuration.h"
#ifndef HAS_FREE_RTOS
namespace concurrency
{
BinarySemaphorePosix::BinarySemaphorePosix()
{
}
BinarySemaphorePosix::BinarySemaphorePosix() {}
BinarySemaphorePosix::~BinarySemaphorePosix()
{
}
BinarySemaphorePosix::~BinarySemaphorePosix() {}
/**
* Returns false if we timed out
@@ -23,13 +19,9 @@ bool BinarySemaphorePosix::take(uint32_t msec)
return false;
}
void BinarySemaphorePosix::give()
{
}
void BinarySemaphorePosix::give() {}
IRAM_ATTR void BinarySemaphorePosix::giveFromISR(BaseType_t *pxHigherPriorityTaskWoken)
{
}
IRAM_ATTR void BinarySemaphorePosix::giveFromISR(BaseType_t *pxHigherPriorityTaskWoken) {}
} // namespace concurrency

View File

@@ -1,5 +1,5 @@
#include "configuration.h"
#include "concurrency/InterruptableDelay.h"
#include "configuration.h"
namespace concurrency
{

View File

@@ -2,7 +2,6 @@
#include "../freertosinc.h"
#ifdef HAS_FREE_RTOS
#include "concurrency/BinarySemaphoreFreeRTOS.h"
#define BinarySemaphore BinarySemaphoreFreeRTOS

View File

@@ -1,5 +1,5 @@
#include "configuration.h"
#include "Lock.h"
#include "configuration.h"
#include <cassert>
namespace concurrency

View File

@@ -1,7 +1,8 @@
#include "configuration.h"
#include "LockGuard.h"
#include "configuration.h"
namespace concurrency {
namespace concurrency
{
LockGuard::LockGuard(Lock *lock) : lock(lock)
{

View File

@@ -2,7 +2,8 @@
#include "Lock.h"
namespace concurrency {
namespace concurrency
{
/**
* @brief RAII lock guard

View File

@@ -1,7 +1,6 @@
#include "configuration.h"
#include "NotifiedWorkerThread.h"
#include "configuration.h"
#include "main.h"
#include <assert.h>
namespace concurrency
{
@@ -81,11 +80,9 @@ void NotifiedWorkerThread::checkNotification()
}
}
int32_t NotifiedWorkerThread::runOnce()
{
enabled = false; // Only run once per notification
enabled = false; // Only run once per notification
checkNotification();
return RUN_SAME;

View File

@@ -41,9 +41,9 @@ class NotifiedWorkerThread : public OSThread
/// just calls checkNotification()
virtual int32_t runOnce() override;
/// Sometimes we might want to check notifications independently of when our thread was getting woken up (i.e. if we are about to change
/// radio transmit/receive modes we want to handle any pending interrupts first). You can call this method and if any notifications are currently
/// pending they will be handled immediately.
/// Sometimes we might want to check notifications independently of when our thread was getting woken up (i.e. if we are about
/// to change radio transmit/receive modes we want to handle any pending interrupts first). You can call this method and if
/// any notifications are currently pending they will be handled immediately.
void checkNotification();
private:

View File

@@ -1,5 +1,5 @@
#include "configuration.h"
#include "OSThread.h"
#include "configuration.h"
#include <assert.h>
namespace concurrency
@@ -76,7 +76,7 @@ void OSThread::run()
{
#ifdef DEBUG_HEAP
auto heap = ESP.getFreeHeap();
#endif
#endif
currentThread = this;
auto newDelay = runOnce();
#ifdef DEBUG_HEAP
@@ -95,11 +95,11 @@ void OSThread::run()
currentThread = NULL;
}
int32_t OSThread::disable()
int32_t OSThread::disable()
{
enabled = false;
setInterval(INT32_MAX);
return INT32_MAX;
}

View File

@@ -27,10 +27,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <Arduino.h>
#ifdef RV3028_RTC
#include "Melopero_RV3028.h"
#include "Melopero_RV3028.h"
#endif
#ifdef PCF8563_RTC
#include "pcf8563.h"
#include "pcf8563.h"
#endif
// -----------------------------------------------------------------------------
@@ -42,7 +42,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#error APP_VERSION must be set by the build environment
#endif
// FIXME: This is still needed by the Bluetooth Stack and needs to be replaced by something better. Remnant of the old versioning system.
// FIXME: This is still needed by the Bluetooth Stack and needs to be replaced by something better. Remnant of the old versioning
// system.
#ifndef HW_VERSION
#define HW_VERSION "1.0"
#endif
@@ -64,13 +65,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// Nop definition for these attributes that are specific to ESP32
#ifndef EXT_RAM_ATTR
#define EXT_RAM_ATTR
#define EXT_RAM_ATTR
#endif
#ifndef IRAM_ATTR
#define IRAM_ATTR
#define IRAM_ATTR
#endif
#ifndef RTC_DATA_ATTR
#define RTC_DATA_ATTR
#define RTC_DATA_ATTR
#endif
// -----------------------------------------------------------------------------
@@ -80,7 +81,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// Disable use of the NTP library and related features
// #define DISABLE_NTP
// Disable the welcome screen and allow
// Disable the welcome screen and allow
//#define DISABLE_WELCOME_UNSET
// -----------------------------------------------------------------------------
@@ -115,6 +116,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define LPS22HB_ADDR 0x5C
#define LPS22HB_ADDR_ALT 0x5D
#define SHT31_ADDR 0x44
#define PMSA0031_ADDR 0x12
// -----------------------------------------------------------------------------
// Security
@@ -135,49 +137,49 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* Step #1: offer chance for variant-specific defines */
#include "variant.h"
/* Step #2: follow with defines common to the architecture;
/* Step #2: follow with defines common to the architecture;
also enable HAS_ option not specifically disabled by variant.h */
#include "architecture.h"
/* Step #3: mop up with disabled values for HAS_ options not handled by the above two */
#ifndef HAS_WIFI
#define HAS_WIFI 0
#define HAS_WIFI 0
#endif
#ifndef HAS_ETHERNET
#define HAS_ETHERNET 0
#define HAS_ETHERNET 0
#endif
#ifndef HAS_SCREEN
#define HAS_SCREEN 0
#define HAS_SCREEN 0
#endif
#ifndef HAS_WIRE
#define HAS_WIRE 0
#define HAS_WIRE 0
#endif
#ifndef HAS_GPS
#define HAS_GPS 0
#define HAS_GPS 0
#endif
#ifndef HAS_BUTTON
#define HAS_BUTTON 0
#define HAS_BUTTON 0
#endif
#ifndef HAS_TELEMETRY
#define HAS_TELEMETRY 0
#define HAS_TELEMETRY 0
#endif
#ifndef HAS_RADIO
#define HAS_RADIO 0
#define HAS_RADIO 0
#endif
#ifndef HAS_RTC
#define HAS_RTC 0
#define HAS_RTC 0
#endif
#ifndef HAS_CPU_SHUTDOWN
#define HAS_CPU_SHUTDOWN 0
#define HAS_CPU_SHUTDOWN 0
#endif
#ifndef HAS_BLUETOOTH
#define HAS_BLUETOOTH 0
#define HAS_BLUETOOTH 0
#endif
#include "RF95Configuration.h"
#include "DebugConfiguration.h"
#include "RF95Configuration.h"
#ifndef HW_VENDOR
#error HW_VENDOR must be defined
#error HW_VENDOR must be defined
#endif

View File

@@ -6,42 +6,49 @@
void d_writeCommand(uint8_t c)
{
SPI1.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0));
if (PIN_EINK_DC >= 0) digitalWrite(PIN_EINK_DC, LOW);
if (PIN_EINK_CS >= 0) digitalWrite(PIN_EINK_CS, LOW);
SPI1.transfer(c);
if (PIN_EINK_CS >= 0) digitalWrite(PIN_EINK_CS, HIGH);
if (PIN_EINK_DC >= 0) digitalWrite(PIN_EINK_DC, HIGH);
SPI1.endTransaction();
SPI1.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0));
if (PIN_EINK_DC >= 0)
digitalWrite(PIN_EINK_DC, LOW);
if (PIN_EINK_CS >= 0)
digitalWrite(PIN_EINK_CS, LOW);
SPI1.transfer(c);
if (PIN_EINK_CS >= 0)
digitalWrite(PIN_EINK_CS, HIGH);
if (PIN_EINK_DC >= 0)
digitalWrite(PIN_EINK_DC, HIGH);
SPI1.endTransaction();
}
void d_writeData(uint8_t d)
{
SPI1.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0));
if (PIN_EINK_CS >= 0) digitalWrite(PIN_EINK_CS, LOW);
SPI1.transfer(d);
if (PIN_EINK_CS >= 0) digitalWrite(PIN_EINK_CS, HIGH);
SPI1.endTransaction();
SPI1.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0));
if (PIN_EINK_CS >= 0)
digitalWrite(PIN_EINK_CS, LOW);
SPI1.transfer(d);
if (PIN_EINK_CS >= 0)
digitalWrite(PIN_EINK_CS, HIGH);
SPI1.endTransaction();
}
unsigned long d_waitWhileBusy(uint16_t busy_time)
{
if (PIN_EINK_BUSY >= 0)
{
delay(1); // add some margin to become active
unsigned long start = micros();
while (1)
{
if (digitalRead(PIN_EINK_BUSY) != HIGH) break;
delay(1);
if (digitalRead(PIN_EINK_BUSY) != HIGH) break;
if (micros() - start > 10000000) break;
}
unsigned long elapsed = micros() - start;
(void) start;
return elapsed;
}
else return busy_time;
if (PIN_EINK_BUSY >= 0) {
delay(1); // add some margin to become active
unsigned long start = micros();
while (1) {
if (digitalRead(PIN_EINK_BUSY) != HIGH)
break;
delay(1);
if (digitalRead(PIN_EINK_BUSY) != HIGH)
break;
if (micros() - start > 10000000)
break;
}
unsigned long elapsed = micros() - start;
(void)start;
return elapsed;
} else
return busy_time;
}
void scanEInkDevice(void)
@@ -51,10 +58,10 @@ void scanEInkDevice(void)
d_writeData(0x83);
d_writeCommand(0x20);
eink_found = (d_waitWhileBusy(150) > 0) ? true : false;
if(eink_found)
LOG_DEBUG("EInk display found\n");
if (eink_found)
LOG_DEBUG("EInk display found\n");
else
LOG_DEBUG("EInk display not found\n");
LOG_DEBUG("EInk display not found\n");
SPI1.end();
}
#endif

View File

@@ -1,11 +1,11 @@
#include "../configuration.h"
#include "../main.h"
#include "mesh/generated/meshtastic/telemetry.pb.h"
#include <Wire.h>
#include "mesh/generated/telemetry.pb.h"
// AXP192 and AXP2101 have the same device address, we just need to identify it in Power.cpp
#ifndef XPOWERS_AXP192_AXP2101_ADDRESS
#define XPOWERS_AXP192_AXP2101_ADDRESS 0x34
#define XPOWERS_AXP192_AXP2101_ADDRESS 0x34
#endif
#if HAS_WIRE
@@ -16,27 +16,27 @@ void printATECCInfo()
atecc.readConfigZone(false);
LOG_DEBUG("ATECC608B Serial Number: ");
for (int i = 0 ; i < 9 ; i++) {
LOG_DEBUG("%02x",atecc.serialNumber[i]);
for (int i = 0; i < 9; i++) {
LOG_DEBUG("%02x", atecc.serialNumber[i]);
}
LOG_DEBUG(", Rev Number: ");
for (int i = 0 ; i < 4 ; i++) {
LOG_DEBUG("%02x",atecc.revisionNumber[i]);
for (int i = 0; i < 4; i++) {
LOG_DEBUG("%02x", atecc.revisionNumber[i]);
}
LOG_DEBUG("\n");
LOG_DEBUG("ATECC608B Config %s",atecc.configLockStatus ? "Locked" : "Unlocked");
LOG_DEBUG(", Data %s",atecc.dataOTPLockStatus ? "Locked" : "Unlocked");
LOG_DEBUG(", Slot 0 %s\n",atecc.slot0LockStatus ? "Locked" : "Unlocked");
LOG_DEBUG("ATECC608B Config %s", atecc.configLockStatus ? "Locked" : "Unlocked");
LOG_DEBUG(", Data %s", atecc.dataOTPLockStatus ? "Locked" : "Unlocked");
LOG_DEBUG(", Slot 0 %s\n", atecc.slot0LockStatus ? "Locked" : "Unlocked");
if (atecc.configLockStatus && atecc.dataOTPLockStatus && atecc.slot0LockStatus) {
if (atecc.generatePublicKey() == false) {
LOG_DEBUG("ATECC608B Error generating public key\n");
} else {
LOG_DEBUG("ATECC608B Public Key: ");
for (int i = 0 ; i < 64 ; i++) {
LOG_DEBUG("%02x",atecc.publicKey64Bytes[i]);
for (int i = 0; i < 64; i++) {
LOG_DEBUG("%02x", atecc.publicKey64Bytes[i]);
}
LOG_DEBUG("\n");
}
@@ -44,7 +44,8 @@ void printATECCInfo()
#endif
}
uint16_t getRegisterValue(uint8_t address, uint8_t reg, uint8_t length) {
uint16_t getRegisterValue(uint8_t address, uint8_t reg, uint8_t length)
{
uint16_t value = 0x00;
Wire.beginTransmission(address);
Wire.write(reg);
@@ -54,7 +55,7 @@ uint16_t getRegisterValue(uint8_t address, uint8_t reg, uint8_t length) {
LOG_DEBUG("Wire.available() = %d\n", Wire.available());
if (Wire.available() == 2) {
// Read MSB, then LSB
value = (uint16_t)Wire.read() << 8;
value = (uint16_t)Wire.read() << 8;
value |= Wire.read();
} else if (Wire.available()) {
value = Wire.read();
@@ -81,7 +82,7 @@ uint8_t oled_probe(byte addr)
if (r == 0x08 || r == 0x00) {
o_probe = 2; // SH1106
} else if ( r == 0x03 || r == 0x04 || r == 0x06 || r == 0x07) {
} else if (r == 0x03 || r == 0x04 || r == 0x06 || r == 0x07) {
o_probe = 1; // SSD1306
}
c++;
@@ -126,17 +127,17 @@ void scanI2Cdevice()
}
#endif
#ifdef RV3028_RTC
if (addr == RV3028_RTC){
if (addr == RV3028_RTC) {
rtc_found = addr;
LOG_INFO("RV3028 RTC found\n");
Melopero_RV3028 rtc;
rtc.initI2C();
rtc.writeToRegister(0x35,0x07); // no Clkout
rtc.writeToRegister(0x37,0xB4);
rtc.writeToRegister(0x35, 0x07); // no Clkout
rtc.writeToRegister(0x37, 0xB4);
}
#endif
#ifdef PCF8563_RTC
if (addr == PCF8563_RTC){
if (addr == PCF8563_RTC) {
rtc_found = addr;
LOG_INFO("PCF8563 RTC found\n");
}
@@ -167,13 +168,13 @@ void scanI2Cdevice()
registerValue = getRegisterValue(addr, 0xD0, 1); // GET_ID
if (registerValue == 0x61) {
LOG_INFO("BME-680 sensor found at address 0x%x\n", (uint8_t)addr);
nodeTelemetrySensorsMap[TelemetrySensorType_BME680] = addr;
nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_BME680] = addr;
} else if (registerValue == 0x60) {
LOG_INFO("BME-280 sensor found at address 0x%x\n", (uint8_t)addr);
nodeTelemetrySensorsMap[TelemetrySensorType_BME280] = addr;
nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_BME280] = addr;
} else {
LOG_INFO("BMP-280 sensor found at address 0x%x\n", (uint8_t)addr);
nodeTelemetrySensorsMap[TelemetrySensorType_BMP280] = addr;
nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_BMP280] = addr;
}
}
if (addr == INA_ADDR || addr == INA_ADDR_ALTERNATE) {
@@ -181,41 +182,45 @@ void scanI2Cdevice()
LOG_DEBUG("Register MFG_UID: 0x%x\n", registerValue);
if (registerValue == 0x5449) {
LOG_INFO("INA260 sensor found at address 0x%x\n", (uint8_t)addr);
nodeTelemetrySensorsMap[TelemetrySensorType_INA260] = addr;
nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA260] = addr;
} else { // Assume INA219 if INA260 ID is not found
LOG_INFO("INA219 sensor found at address 0x%x\n", (uint8_t)addr);
nodeTelemetrySensorsMap[TelemetrySensorType_INA219] = addr;
nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219] = addr;
}
}
if (addr == MCP9808_ADDR) {
nodeTelemetrySensorsMap[TelemetrySensorType_MCP9808] = addr;
nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_MCP9808] = addr;
LOG_INFO("MCP9808 sensor found\n");
}
if (addr == SHT31_ADDR) {
LOG_INFO("SHT31 sensor found\n");
nodeTelemetrySensorsMap[TelemetrySensorType_SHT31] = addr;
nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_SHT31] = addr;
}
if (addr == SHTC3_ADDR) {
LOG_INFO("SHTC3 sensor found\n");
nodeTelemetrySensorsMap[TelemetrySensorType_SHTC3] = addr;
nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_SHTC3] = addr;
}
if (addr == LPS22HB_ADDR || addr == LPS22HB_ADDR_ALT) {
LOG_INFO("LPS22HB sensor found\n");
nodeTelemetrySensorsMap[TelemetrySensorType_LPS22] = addr;
nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_LPS22] = addr;
}
// High rate sensors, will be processed internally
if (addr == QMC6310_ADDR) {
LOG_INFO("QMC6310 Highrate 3-Axis magnetic sensor found\n");
nodeTelemetrySensorsMap[TelemetrySensorType_QMC6310] = addr;
nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_QMC6310] = addr;
}
if (addr == QMI8658_ADDR) {
LOG_INFO("QMI8658 Highrate 6-Axis inertial measurement sensor found\n");
nodeTelemetrySensorsMap[TelemetrySensorType_QMI8658] = addr;
nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_QMI8658] = addr;
}
if (addr == QMC5883L_ADDR) {
LOG_INFO("QMC5883L Highrate 3-Axis magnetic sensor found\n");
nodeTelemetrySensorsMap[TelemetrySensorType_QMC5883L] = addr;
nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_QMC5883L] = addr;
}
if (addr == PMSA0031_ADDR) {
LOG_INFO("PMSA0031 air quality sensor found\n");
nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_PMSA003I] = addr;
}
} else if (err == 4) {
LOG_ERROR("Unknow error at address 0x%x\n", addr);
@@ -225,7 +230,7 @@ void scanI2Cdevice()
if (nDevices == 0)
LOG_INFO("No I2C devices found\n");
else
LOG_INFO("%i I2C devices found\n",nDevices);
LOG_INFO("%i I2C devices found\n", nDevices);
}
#else
void scanI2Cdevice() {}

View File

@@ -2,10 +2,11 @@
#include <Arduino.h>
#include "mesh/generated/mesh.pb.h" // For CriticalErrorCode
#include "mesh/generated/meshtastic/mesh.pb.h" // For CriticalErrorCode
/// A macro that include filename and line
#define RECORD_CRITICALERROR(code) recordCriticalError(code, __LINE__, __FILE__)
/// Record an error that should be reported via analytics
void recordCriticalError(CriticalErrorCode code = CriticalErrorCode_UNSPECIFIED, uint32_t address = 0, const char *filename = NULL);
void recordCriticalError(meshtastic_CriticalErrorCode code = meshtastic_CriticalErrorCode_UNSPECIFIED, uint32_t address = 0,
const char *filename = NULL);

View File

@@ -3,7 +3,6 @@
#include "RTC.h"
#include "configuration.h"
#include "sleep.h"
#include <assert.h>
// If we have a serial GPS port it will not be null
#ifdef GPS_SERIAL_NUM
@@ -22,45 +21,45 @@ GPS *gps;
/// only init that port once.
static bool didSerialInit;
bool GPS::getACK(uint8_t c, uint8_t i) {
uint8_t b;
uint8_t ack = 0;
const uint8_t ackP[2] = {c, i};
uint8_t buf[10] = {0xB5, 0x62, 0x05, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00};
unsigned long startTime = millis();
bool GPS::getACK(uint8_t c, uint8_t i)
{
uint8_t b;
uint8_t ack = 0;
const uint8_t ackP[2] = {c, i};
uint8_t buf[10] = {0xB5, 0x62, 0x05, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00};
unsigned long startTime = millis();
for (int j = 2; j < 6; j++) {
buf[8] += buf[j];
buf[9] += buf[8];
}
for (int j = 2; j < 6; j++) {
buf[8] += buf[j];
buf[9] += buf[8];
}
for (int j = 0; j < 2; j++) {
buf[6 + j] = ackP[j];
buf[8] += buf[6 + j];
buf[9] += buf[8];
}
for (int j = 0; j < 2; j++) {
buf[6 + j] = ackP[j];
buf[8] += buf[6 + j];
buf[9] += buf[8];
}
while (1) {
if (ack > 9) {
return true;
while (1) {
if (ack > 9) {
return true;
}
if (millis() - startTime > 1000) {
return false;
}
if (_serial_gps->available()) {
b = _serial_gps->read();
if (b == buf[ack]) {
ack++;
} else {
ack = 0;
}
}
}
if (millis() - startTime > 1000) {
return false;
}
if (_serial_gps->available()) {
b = _serial_gps->read();
if (b == buf[ack]) {
ack++;
}
else {
ack = 0;
}
}
}
}
/**
* @brief
* @brief
* @note New method, this method can wait for the specified class and message ID, and return the payload
* @param *buffer: The message buffer, if there is a response payload message, it will be returned through the buffer parameter
* @param size: size of buffer
@@ -70,22 +69,22 @@ bool GPS::getACK(uint8_t c, uint8_t i) {
*/
int GPS::getAck(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t requestedID)
{
uint16_t ubxFrameCounter = 0;
uint32_t startTime = millis();
uint16_t needRead;
uint16_t ubxFrameCounter = 0;
uint32_t startTime = millis();
uint16_t needRead;
while (millis() - startTime < 800) {
while (_serial_gps->available()) {
int c = _serial_gps->read();
switch (ubxFrameCounter) {
case 0:
//ubxFrame 'μ'
if (c == 0xB5) {
// ubxFrame 'μ'
if (c == 0xB5) {
ubxFrameCounter++;
}
break;
case 1:
//ubxFrame 'b'
// ubxFrame 'b'
if (c == 0x62) {
ubxFrameCounter++;
} else {
@@ -93,7 +92,7 @@ int GPS::getAck(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t
}
break;
case 2:
//Class
// Class
if (c == requestedClass) {
ubxFrameCounter++;
} else {
@@ -101,7 +100,7 @@ int GPS::getAck(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t
}
break;
case 3:
//Message ID
// Message ID
if (c == requestedID) {
ubxFrameCounter++;
} else {
@@ -109,13 +108,13 @@ int GPS::getAck(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t
}
break;
case 4:
//Payload lenght lsb
// Payload lenght lsb
needRead = c;
ubxFrameCounter++;
break;
case 5:
//Payload lenght msb
needRead |= (c << 8);
// Payload lenght msb
needRead |= (c << 8);
ubxFrameCounter++;
break;
case 6:
@@ -146,41 +145,41 @@ bool GPS::setupGPS()
didSerialInit = true;
#ifdef ARCH_ESP32
// In esp32 framework, setRxBufferSize needs to be initialized before Serial
_serial_gps->setRxBufferSize(2048); // the default is 256
// In esp32 framework, setRxBufferSize needs to be initialized before Serial
_serial_gps->setRxBufferSize(2048); // the default is 256
#endif
// if the overrides are not dialled in, set them from the board definitions, if they exist
// if the overrides are not dialled in, set them from the board definitions, if they exist
#if defined(GPS_RX_PIN)
if (!config.position.rx_gpio)
config.position.rx_gpio = GPS_RX_PIN;
if (!config.position.rx_gpio)
config.position.rx_gpio = GPS_RX_PIN;
#endif
#if defined(GPS_TX_PIN)
if (!config.position.tx_gpio)
config.position.tx_gpio = GPS_TX_PIN;
if (!config.position.tx_gpio)
config.position.tx_gpio = GPS_TX_PIN;
#endif
// ESP32 has a special set of parameters vs other arduino ports
#if defined(ARCH_ESP32)
if(config.position.rx_gpio)
if (config.position.rx_gpio)
_serial_gps->begin(GPS_BAUDRATE, SERIAL_8N1, config.position.rx_gpio, config.position.tx_gpio);
#else
_serial_gps->begin(GPS_BAUDRATE);
#endif
/*
* T-Beam-S3-Core will be preset to use gps Probe here, and other boards will not be changed first
*/
gnssModel = probe();
* T-Beam-S3-Core will be preset to use gps Probe here, and other boards will not be changed first
*/
gnssModel = probe();
if(gnssModel == GNSS_MODEL_MTK){
if (gnssModel == GNSS_MODEL_MTK) {
/*
* t-beam-s3-core uses the same L76K GNSS module as t-echo.
* Unlike t-echo, L76K uses 9600 baud rate for communication by default.
* */
// _serial_gps->begin(9600); //The baud rate of 9600 has been initialized at the beginning of setupGPS, this line is the redundant part
// delay(250);
* t-beam-s3-core uses the same L76K GNSS module as t-echo.
* Unlike t-echo, L76K uses 9600 baud rate for communication by default.
* */
// _serial_gps->begin(9600); //The baud rate of 9600 has been initialized at the beginning of setupGPS, this line
// is the redundant part delay(250);
// Initialize the L76K Chip, use GPS + GLONASS
_serial_gps->write("$PCAS04,5*1C\r\n");
@@ -191,11 +190,10 @@ if (!config.position.tx_gpio)
// Switch to Vehicle Mode, since SoftRF enables Aviation < 2g
_serial_gps->write("$PCAS11,3*1E\r\n");
delay(250);
}else if(gnssModel == GNSS_MODEL_UBLOX){
} else if (gnssModel == GNSS_MODEL_UBLOX) {
/*
tips: NMEA Only should not be set here, otherwise initializing Ublox gnss module again after
tips: NMEA Only should not be set here, otherwise initializing Ublox gnss module again after
setting will not output command messages in UART1, resulting in unrecognized module information
// Set the UART port to output NMEA only
@@ -205,13 +203,14 @@ if (!config.position.tx_gpio)
if (!getACK(0x06, 0x00)) {
LOG_WARN("Unable to enable NMEA Mode.\n");
return true;
}
}
*/
// ublox-M10S can be compatible with UBLOX traditional protocol, so the following sentence settings are also valid
// ublox-M10S can be compatible with UBLOX traditional protocol, so the following sentence settings are also valid
// disable GGL
byte _message_GGL[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x05, 0x3A};
byte _message_GGL[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x01,
0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x05, 0x3A};
_serial_gps->write(_message_GGL, sizeof(_message_GGL));
if (!getACK(0x06, 0x01)) {
LOG_WARN("Unable to disable NMEA GGL.\n");
@@ -219,7 +218,8 @@ if (!config.position.tx_gpio)
}
// disable GSA
byte _message_GSA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x02, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x06, 0x41};
byte _message_GSA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x02,
0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x06, 0x41};
_serial_gps->write(_message_GSA, sizeof(_message_GSA));
if (!getACK(0x06, 0x01)) {
LOG_WARN("Unable to disable NMEA GSA.\n");
@@ -227,7 +227,8 @@ if (!config.position.tx_gpio)
}
// disable GSV
byte _message_GSV[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x03, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x07, 0x48};
byte _message_GSV[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x03,
0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x07, 0x48};
_serial_gps->write(_message_GSV, sizeof(_message_GSV));
if (!getACK(0x06, 0x01)) {
LOG_WARN("Unable to disable NMEA GSV.\n");
@@ -235,7 +236,8 @@ if (!config.position.tx_gpio)
}
// disable VTG
byte _message_VTG[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x05, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x09, 0x56};
byte _message_VTG[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x05,
0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x09, 0x56};
_serial_gps->write(_message_VTG, sizeof(_message_VTG));
if (!getACK(0x06, 0x01)) {
LOG_WARN("Unable to disable NMEA VTG.\n");
@@ -243,7 +245,8 @@ if (!config.position.tx_gpio)
}
// enable RMC
byte _message_RMC[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x09, 0x54};
byte _message_RMC[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x04,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x09, 0x54};
_serial_gps->write(_message_RMC, sizeof(_message_RMC));
if (!getACK(0x06, 0x01)) {
LOG_WARN("Unable to enable NMEA RMC.\n");
@@ -251,7 +254,8 @@ if (!config.position.tx_gpio)
}
// enable GGA
byte _message_GGA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x05, 0x38};
byte _message_GGA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x00,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x05, 0x38};
_serial_gps->write(_message_GGA, sizeof(_message_GGA));
if (!getACK(0x06, 0x01)) {
LOG_WARN("Unable to enable NMEA GGA.\n");
@@ -271,9 +275,9 @@ bool GPS::setup()
#endif
#ifdef HAS_PMU
if(config.position.gps_enabled){
setGPSPower(true);
}
if (config.position.gps_enabled) {
setGPSPower(true);
}
#endif
#ifdef PIN_GPS_RESET
@@ -290,7 +294,8 @@ if(config.position.gps_enabled){
notifyDeepSleepObserver.observe(&notifyDeepSleep);
notifyGPSSleepObserver.observe(&notifyGPSSleep);
}
if (config.position.gps_enabled==false) {
if (config.position.gps_enabled == false && config.position.fixed_position == false) {
setAwake(false);
doGPSpowersave(false);
}
@@ -397,12 +402,13 @@ uint32_t GPS::getSleepTime() const
uint32_t t = config.position.gps_update_interval;
bool gps_enabled = config.position.gps_enabled;
if (!gps_enabled)
// We'll not need the GPS thread to wake up again after first acq. with fixed position.
if (!gps_enabled || config.position.fixed_position)
t = UINT32_MAX; // Sleep forever now
if (t == UINT32_MAX)
return t; // already maxint
return t * 1000;
}
@@ -422,16 +428,21 @@ void GPS::publishUpdate()
int32_t GPS::runOnce()
{
// Repeaters have no need for GPS
if (config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER)
disable();
if (whileIdle()) {
// if we have received valid NMEA claim we are connected
setConnected();
} else {
if((config.position.gps_enabled == 1) && (gnssModel == GNSS_MODEL_UBLOX)){
if ((config.position.gps_enabled == 1) && (gnssModel == GNSS_MODEL_UBLOX)) {
// reset the GPS on next bootup
if(devicestate.did_gps_reset && (millis() > 60000) && !hasFlow()) {
if (devicestate.did_gps_reset && (millis() > 60000) && !hasFlow()) {
LOG_DEBUG("GPS is not communicating, trying factory reset on next bootup.\n");
devicestate.did_gps_reset = false;
nodeDB.saveDeviceStateToDisk();
disable(); // Stop the GPS thread as it can do nothing useful until next reboot.
}
}
}
@@ -481,7 +492,7 @@ int32_t GPS::runOnce()
if (hasValidLocation) {
LOG_DEBUG("hasValidLocation FALLING EDGE (last read: %d)\n", gotLoc);
}
p = Position_init_default;
p = meshtastic_Position_init_default;
hasValidLocation = false;
}
@@ -493,6 +504,14 @@ int32_t GPS::runOnce()
// If state has changed do a publish
publishUpdate();
if (!(fixeddelayCtr >= 20) && config.position.fixed_position && hasValidLocation) {
fixeddelayCtr++;
// LOG_DEBUG("Our delay counter is %d\n", fixeddelayCtr);
if (fixeddelayCtr >= 20) {
doGPSpowersave(false);
forceWake(false);
}
}
// 9600bps is approx 1 byte per msec, so considering our buffer size we never need to wake more often than 200ms
// if not awake we can run super infrquently (once every 5 secs?) to see if we need to wake.
return isAwake ? GPS_THREAD_INTERVAL : 5000;
@@ -545,10 +564,10 @@ GnssModel_t GPS::probe()
// we use autodetect, only T-BEAM S3 for now...
uint8_t buffer[256];
/*
* The GNSS module information variable is temporarily placed inside the function body,
* if it needs to be used elsewhere, it can be moved to the outside
* */
struct uBloxGnssModelInfo info ;
* The GNSS module information variable is temporarily placed inside the function body,
* if it needs to be used elsewhere, it can be moved to the outside
* */
struct uBloxGnssModelInfo info;
memset(&info, 0, sizeof(struct uBloxGnssModelInfo));
@@ -562,10 +581,10 @@ GnssModel_t GPS::probe()
while (millis() < startTimeout) {
if (_serial_gps->available()) {
String ver = _serial_gps->readStringUntil('\r');
// Get module info , If the correct header is returned,
// Get module info , If the correct header is returned,
// it can be determined that it is the MTK chip
int index = ver.indexOf("$");
if(index != -1){
if (index != -1) {
ver = ver.substring(index);
if (ver.startsWith("$GPTXT,01,01,02")) {
LOG_INFO("L76K GNSS init succeeded, using L76K GNSS Module\n");
@@ -574,7 +593,6 @@ GnssModel_t GPS::probe()
}
}
}
uint8_t cfg_rate[] = {0xB5, 0x62, 0x06, 0x08, 0x00, 0x00, 0x0E, 0x30};
_serial_gps->write(cfg_rate, sizeof(cfg_rate));
@@ -582,10 +600,10 @@ GnssModel_t GPS::probe()
if (!getAck(buffer, 256, 0x06, 0x08)) {
LOG_WARN("Failed to find UBlox & MTK GNSS Module\n");
return GNSS_MODEL_UNKONW;
}
}
// Get Ublox gnss module hardware and software info
uint8_t cfg_get_hw[] = {0xB5, 0x62, 0x0A, 0x04, 0x00, 0x00, 0x0E, 0x34};
uint8_t cfg_get_hw[] = {0xB5, 0x62, 0x0A, 0x04, 0x00, 0x00, 0x0E, 0x34};
_serial_gps->write(cfg_get_hw, sizeof(cfg_get_hw));
uint16_t len = getAck(buffer, 256, 0x0A, 0x04);
@@ -612,27 +630,27 @@ GnssModel_t GPS::probe()
}
LOG_DEBUG("Module Info : \n");
LOG_DEBUG("Soft version: %s\n",info.swVersion);
LOG_DEBUG("Hard version: %s\n",info.hwVersion);
LOG_DEBUG("Extensions:%d\n",info.extensionNo);
LOG_DEBUG("Soft version: %s\n", info.swVersion);
LOG_DEBUG("Hard version: %s\n", info.hwVersion);
LOG_DEBUG("Extensions:%d\n", info.extensionNo);
for (int i = 0; i < info.extensionNo; i++) {
LOG_DEBUG(" %s\n",info.extension[i]);
LOG_DEBUG(" %s\n", info.extension[i]);
}
memset(buffer,0,sizeof(buffer));
memset(buffer, 0, sizeof(buffer));
//tips: extensionNo field is 0 on some 6M GNSS modules
// tips: extensionNo field is 0 on some 6M GNSS modules
for (int i = 0; i < info.extensionNo; ++i) {
if (!strncmp(info.extension[i], "OD=", 3)) {
strcpy((char *)buffer, &(info.extension[i][3]));
LOG_DEBUG("GetModel:%s\n",(char *)buffer);
strncpy((char *)buffer, &(info.extension[i][3]), sizeof(buffer));
LOG_DEBUG("GetModel:%s\n", (char *)buffer);
}
}
}
if (strlen((char*)buffer)) {
LOG_INFO("UBlox GNSS init succeeded, using UBlox %s GNSS Module\n" , buffer);
}else{
if (strlen((char *)buffer)) {
LOG_INFO("UBlox GNSS init succeeded, using UBlox %s GNSS Module\n", buffer);
} else {
LOG_INFO("UBlox GNSS init succeeded, using UBlox GNSS Module\n");
}
@@ -663,8 +681,7 @@ GPS *createGps()
new_gps->setup();
return new_gps;
}
}
else{
} else {
GPS *new_gps = new NMEAGPS();
new_gps->setup();
return new_gps;

View File

@@ -4,19 +4,18 @@
#include "Observer.h"
#include "concurrency/OSThread.h"
struct uBloxGnssModelInfo {
char swVersion[30];
char hwVersion[10];
struct uBloxGnssModelInfo {
char swVersion[30];
char hwVersion[10];
uint8_t extensionNo;
char extension[10][30];
} ;
char extension[10][30];
};
typedef enum{
GNSS_MODEL_MTK,
GNSS_MODEL_UBLOX,
GNSS_MODEL_UNKONW,
}GnssModel_t;
typedef enum {
GNSS_MODEL_MTK,
GNSS_MODEL_UBLOX,
GNSS_MODEL_UNKONW,
} GnssModel_t;
// Generate a string representation of DOP
const char *getDOPString(uint32_t dop);
@@ -55,7 +54,7 @@ class GPS : private concurrency::OSThread
/** If !NULL we will use this serial port to construct our GPS */
static HardwareSerial *_serial_gps;
Position p = Position_init_default;
meshtastic_Position p = meshtastic_Position_init_default;
GPS() : concurrency::OSThread("GPS") {}
@@ -78,7 +77,7 @@ class GPS : private concurrency::OSThread
/// Return true if we are connected to a GPS
bool isConnected() const { return hasGPS; }
bool isPowerSaving() const { return !config.position.gps_enabled;}
bool isPowerSaving() const { return !config.position.gps_enabled; }
/**
* Restart our lock attempt - try to get and broadcast a GPS reading ASAP
@@ -164,17 +163,20 @@ class GPS : private concurrency::OSThread
virtual int32_t runOnce() override;
// Get GNSS model
// Get GNSS model
GnssModel_t probe();
int getAck(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t requestedID);
// delay counter to allow more sats before fixed position stops GPS thread
uint8_t fixeddelayCtr = 0;
protected:
GnssModel_t gnssModel = GNSS_MODEL_UNKONW;
};
// Creates an instance of the GPS class.
// Creates an instance of the GPS class.
// Returns the new instance or null if the GPS is not present.
GPS* createGps();
GPS *createGps();
extern GPS *gps;

View File

@@ -1,21 +1,25 @@
#include "GeoCoord.h"
GeoCoord::GeoCoord() {
GeoCoord::GeoCoord()
{
_dirty = true;
}
GeoCoord::GeoCoord (int32_t lat, int32_t lon, int32_t alt) : _latitude(lat), _longitude(lon), _altitude(alt) {
GeoCoord::GeoCoord(int32_t lat, int32_t lon, int32_t alt) : _latitude(lat), _longitude(lon), _altitude(alt)
{
GeoCoord::setCoords();
}
GeoCoord::GeoCoord (float lat, float lon, int32_t alt) : _altitude(alt) {
GeoCoord::GeoCoord(float lat, float lon, int32_t alt) : _altitude(alt)
{
// Change decimial reprsentation to int32_t. I.e., 12.345 becomes 123450000
_latitude = int32_t(lat * 1e+7);
_longitude = int32_t(lon * 1e+7);
GeoCoord::setCoords();
}
GeoCoord::GeoCoord(double lat, double lon, int32_t alt): _altitude(alt) {
GeoCoord::GeoCoord(double lat, double lon, int32_t alt) : _altitude(alt)
{
// Change decimial reprsentation to int32_t. I.e., 12.345 becomes 123450000
_latitude = int32_t(lat * 1e+7);
_longitude = int32_t(lon * 1e+7);
@@ -23,7 +27,8 @@ GeoCoord::GeoCoord(double lat, double lon, int32_t alt): _altitude(alt) {
}
// Initialize all the coordinate systems
void GeoCoord::setCoords() {
void GeoCoord::setCoords()
{
double lat = _latitude * 1e-7;
double lon = _longitude * 1e-7;
GeoCoord::latLongToDMS(lat, lon, _dms);
@@ -34,9 +39,10 @@ void GeoCoord::setCoords() {
_dirty = false;
}
void GeoCoord::updateCoords(int32_t lat, int32_t lon, int32_t alt) {
void GeoCoord::updateCoords(int32_t lat, int32_t lon, int32_t alt)
{
// If marked dirty or new coordiantes
if(_dirty || _latitude != lat || _longitude != lon || _altitude != alt) {
if (_dirty || _latitude != lat || _longitude != lon || _altitude != alt) {
_dirty = true;
_latitude = lat;
_longitude = lon;
@@ -45,25 +51,26 @@ void GeoCoord::updateCoords(int32_t lat, int32_t lon, int32_t alt) {
}
}
void GeoCoord::updateCoords(const double lat, const double lon, const int32_t alt) {
void GeoCoord::updateCoords(const double lat, const double lon, const int32_t alt)
{
int32_t iLat = lat * 1e+7;
int32_t iLon = lon * 1e+7;
// If marked dirty or new coordiantes
if(_dirty || _latitude != iLat || _longitude != iLon || _altitude != alt) {
if (_dirty || _latitude != iLat || _longitude != iLon || _altitude != alt) {
_dirty = true;
_latitude = iLat;
_longitude = iLon;
_altitude = alt;
setCoords();
}
}
void GeoCoord::updateCoords(const float lat, const float lon, const int32_t alt) {
void GeoCoord::updateCoords(const float lat, const float lon, const int32_t alt)
{
int32_t iLat = lat * 1e+7;
int32_t iLon = lon * 1e+7;
// If marked dirty or new coordiantes
if(_dirty || _latitude != iLat || _longitude != iLon || _altitude != alt) {
if (_dirty || _latitude != iLat || _longitude != iLon || _altitude != alt) {
_dirty = true;
_latitude = iLat;
_longitude = iLon;
@@ -73,12 +80,15 @@ void GeoCoord::updateCoords(const float lat, const float lon, const int32_t alt)
}
/**
* Converts lat long coordinates from decimal degrees to degrees minutes seconds format.
* Converts lat long coordinates from decimal degrees to degrees minutes seconds format.
* DD°MM'SS"C DDD°MM'SS"C
*/
void GeoCoord::latLongToDMS(const double lat, const double lon, DMS &dms) {
if (lat < 0) dms.latCP = 'S';
else dms.latCP = 'N';
void GeoCoord::latLongToDMS(const double lat, const double lon, DMS &dms)
{
if (lat < 0)
dms.latCP = 'S';
else
dms.latCP = 'N';
double latDeg = lat;
@@ -90,8 +100,10 @@ void GeoCoord::latLongToDMS(const double lat, const double lon, DMS &dms) {
dms.latMin = floor(latMin);
dms.latSec = (latMin - dms.latMin) * 60;
if (lon < 0) dms.lonCP = 'W';
else dms.lonCP = 'E';
if (lon < 0)
dms.lonCP = 'W';
else
dms.lonCP = 'E';
double lonDeg = lon;
@@ -108,52 +120,64 @@ void GeoCoord::latLongToDMS(const double lat, const double lon, DMS &dms) {
* Converts lat long coordinates to UTM.
* based on this: https://github.com/walvok/LatLonToUTM/blob/master/latlon_utm.ino
*/
void GeoCoord::latLongToUTM(const double lat, const double lon, UTM &utm) {
void GeoCoord::latLongToUTM(const double lat, const double lon, UTM &utm)
{
const std::string latBands = "CDEFGHJKLMNPQRSTUVWXX";
utm.zone = int((lon + 180)/6 + 1);
utm.band = latBands[int(lat/8 + 10)];
double a = 6378137; // WGS84 - equatorial radius
double k0 = 0.9996; // UTM point scale on the central meridian
double eccSquared = 0.00669438; // eccentricity squared
double lonTemp = (lon + 180) - int((lon + 180)/360) * 360 - 180; //Make sure the longitude is between -180.00 .. 179.9
utm.zone = int((lon + 180) / 6 + 1);
utm.band = latBands[int(lat / 8 + 10)];
double a = 6378137; // WGS84 - equatorial radius
double k0 = 0.9996; // UTM point scale on the central meridian
double eccSquared = 0.00669438; // eccentricity squared
double lonTemp = (lon + 180) - int((lon + 180) / 360) * 360 - 180; // Make sure the longitude is between -180.00 .. 179.9
double latRad = toRadians(lat);
double lonRad = toRadians(lonTemp);
// Special Zones for Norway and Svalbard
if( lat >= 56.0 && lat < 64.0 && lonTemp >= 3.0 && lonTemp < 12.0 ) // Norway
if (lat >= 56.0 && lat < 64.0 && lonTemp >= 3.0 && lonTemp < 12.0) // Norway
utm.zone = 32;
if( lat >= 72.0 && lat < 84.0 ) { // Svalbard
if ( lonTemp >= 0.0 && lonTemp < 9.0 ) utm.zone = 31;
else if( lonTemp >= 9.0 && lonTemp < 21.0 ) utm.zone = 33;
else if( lonTemp >= 21.0 && lonTemp < 33.0 ) utm.zone = 35;
else if( lonTemp >= 33.0 && lonTemp < 42.0 ) utm.zone = 37;
if (lat >= 72.0 && lat < 84.0) { // Svalbard
if (lonTemp >= 0.0 && lonTemp < 9.0)
utm.zone = 31;
else if (lonTemp >= 9.0 && lonTemp < 21.0)
utm.zone = 33;
else if (lonTemp >= 21.0 && lonTemp < 33.0)
utm.zone = 35;
else if (lonTemp >= 33.0 && lonTemp < 42.0)
utm.zone = 37;
}
double lonOrigin = (utm.zone - 1)*6 - 180 + 3; // puts origin in middle of zone
double lonOrigin = (utm.zone - 1) * 6 - 180 + 3; // puts origin in middle of zone
double lonOriginRad = toRadians(lonOrigin);
double eccPrimeSquared = (eccSquared)/(1 - eccSquared);
double N = a/sqrt(1 - eccSquared*sin(latRad)*sin(latRad));
double T = tan(latRad)*tan(latRad);
double C = eccPrimeSquared*cos(latRad)*cos(latRad);
double A = cos(latRad)*(lonRad - lonOriginRad);
double M = a*((1 - eccSquared/4 - 3*eccSquared*eccSquared/64 - 5*eccSquared*eccSquared*eccSquared/256)*latRad
- (3*eccSquared/8 + 3*eccSquared*eccSquared/32 + 45*eccSquared*eccSquared*eccSquared/1024)*sin(2*latRad)
+ (15*eccSquared*eccSquared/256 + 45*eccSquared*eccSquared*eccSquared/1024)*sin(4*latRad)
- (35*eccSquared*eccSquared*eccSquared/3072)*sin(6*latRad));
utm.easting = (double)(k0*N*(A+(1-T+C)*pow(A, 3)/6 + (5-18*T+T*T+72*C-58*eccPrimeSquared)*A*A*A*A*A/120)
+ 500000.0);
utm.northing = (double)(k0*(M+N*tan(latRad)*(A*A/2+(5-T+9*C+4*C*C)*A*A*A*A/24
+ (61-58*T+T*T+600*C-330*eccPrimeSquared)*A*A*A*A*A*A/720)));
if(lat < 0)
utm.northing += 10000000.0; //10000000 meter offset for southern hemisphere
double eccPrimeSquared = (eccSquared) / (1 - eccSquared);
double N = a / sqrt(1 - eccSquared * sin(latRad) * sin(latRad));
double T = tan(latRad) * tan(latRad);
double C = eccPrimeSquared * cos(latRad) * cos(latRad);
double A = cos(latRad) * (lonRad - lonOriginRad);
double M =
a * ((1 - eccSquared / 4 - 3 * eccSquared * eccSquared / 64 - 5 * eccSquared * eccSquared * eccSquared / 256) * latRad -
(3 * eccSquared / 8 + 3 * eccSquared * eccSquared / 32 + 45 * eccSquared * eccSquared * eccSquared / 1024) *
sin(2 * latRad) +
(15 * eccSquared * eccSquared / 256 + 45 * eccSquared * eccSquared * eccSquared / 1024) * sin(4 * latRad) -
(35 * eccSquared * eccSquared * eccSquared / 3072) * sin(6 * latRad));
utm.easting = (double)(k0 * N *
(A + (1 - T + C) * pow(A, 3) / 6 +
(5 - 18 * T + T * T + 72 * C - 58 * eccPrimeSquared) * A * A * A * A * A / 120) +
500000.0);
utm.northing =
(double)(k0 * (M + N * tan(latRad) *
(A * A / 2 + (5 - T + 9 * C + 4 * C * C) * A * A * A * A / 24 +
(61 - 58 * T + T * T + 600 * C - 330 * eccPrimeSquared) * A * A * A * A * A * A / 720)));
if (lat < 0)
utm.northing += 10000000.0; // 10000000 meter offset for southern hemisphere
}
// Converts lat long coordinates to an MGRS.
void GeoCoord::latLongToMGRS(const double lat, const double lon, MGRS &mgrs) {
const std::string e100kLetters[3] = { "ABCDEFGH", "JKLMNPQR", "STUVWXYZ" };
const std::string n100kLetters[2] = { "ABCDEFGHJKLMNPQRSTUV", "FGHJKLMNPQRSTUVABCDE" };
void GeoCoord::latLongToMGRS(const double lat, const double lon, MGRS &mgrs)
{
const std::string e100kLetters[3] = {"ABCDEFGH", "JKLMNPQR", "STUVWXYZ"};
const std::string n100kLetters[2] = {"ABCDEFGHJKLMNPQRSTUV", "FGHJKLMNPQRSTUVABCDE"};
UTM utm;
latLongToUTM(lat, lon, utm);
mgrs.zone = utm.zone;
@@ -161,7 +185,7 @@ void GeoCoord::latLongToMGRS(const double lat, const double lon, MGRS &mgrs) {
double col = floor(utm.easting / 100000);
mgrs.east100k = e100kLetters[(mgrs.zone - 1) % 3][col - 1];
double row = (int32_t)floor(utm.northing / 100000.0) % 20;
mgrs.north100k = n100kLetters[(mgrs.zone-1)%2][row];
mgrs.north100k = n100kLetters[(mgrs.zone - 1) % 2][row];
mgrs.easting = (int32_t)utm.easting % 100000;
mgrs.northing = (int32_t)utm.northing % 100000;
}
@@ -170,52 +194,54 @@ void GeoCoord::latLongToMGRS(const double lat, const double lon, MGRS &mgrs) {
* Converts lat long coordinates to Ordnance Survey Grid Reference (UK National Grid Ref).
* Based on: https://www.movable-type.co.uk/scripts/latlong-os-gridref.html
*/
void GeoCoord::latLongToOSGR(const double lat, const double lon, OSGR &osgr) {
void GeoCoord::latLongToOSGR(const double lat, const double lon, OSGR &osgr)
{
const char letter[] = "ABCDEFGHJKLMNOPQRSTUVWXYZ"; // No 'I' in OSGR
double a = 6377563.396; // Airy 1830 semi-major axis
double b = 6356256.909; // Airy 1830 semi-minor axis
double f0 = 0.9996012717; // National Grid point scale factor on the central meridian
double phi0 = toRadians(49);
double a = 6377563.396; // Airy 1830 semi-major axis
double b = 6356256.909; // Airy 1830 semi-minor axis
double f0 = 0.9996012717; // National Grid point scale factor on the central meridian
double phi0 = toRadians(49);
double lambda0 = toRadians(-2);
double n0 = -100000;
double e0 = 400000;
double e2 = 1 - (b*b)/(a*a); // eccentricity squared
double n = (a - b)/(a + b);
double e2 = 1 - (b * b) / (a * a); // eccentricity squared
double n = (a - b) / (a + b);
double osgb_Latitude;
double osgb_Longitude;
convertWGS84ToOSGB36(lat, lon, osgb_Latitude, osgb_Longitude);
double phi = osgb_Latitude; // already in radians
double phi = osgb_Latitude; // already in radians
double lambda = osgb_Longitude; // already in radians
double v = a * f0 / sqrt(1 - e2 * sin(phi) * sin(phi));
double rho = a * f0 * (1 - e2) / pow(1 - e2 * sin(phi) * sin(phi), 1.5);
double eta2 = v / rho - 1;
double mA = (1 + n + (5/4)*n*n + (5/4)*n*n*n) * (phi - phi0);
double mB = (3*n + 3*n*n + (21/8)*n*n*n) * sin(phi - phi0) * cos(phi + phi0);
double mA = (1 + n + (5 / 4) * n * n + (5 / 4) * n * n * n) * (phi - phi0);
double mB = (3 * n + 3 * n * n + (21 / 8) * n * n * n) * sin(phi - phi0) * cos(phi + phi0);
// loss of precision in mC & mD due to floating point rounding can cause innaccuracy of northing by a few meters
double mC = (15/8*n*n + 15/8*n*n*n) * sin(2*(phi - phi0)) * cos(2*(phi + phi0));
double mD = (35/24)*n*n*n * sin(3*(phi - phi0)) * cos(3*(phi + phi0));
double m = b*f0*(mA - mB + mC - mD);
double mC = (15 / 8 * n * n + 15 / 8 * n * n * n) * sin(2 * (phi - phi0)) * cos(2 * (phi + phi0));
double mD = (35 / 24) * n * n * n * sin(3 * (phi - phi0)) * cos(3 * (phi + phi0));
double m = b * f0 * (mA - mB + mC - mD);
double cos3Phi = cos(phi)*cos(phi)*cos(phi);
double cos5Phi = cos3Phi*cos(phi)*cos(phi);
double tan2Phi = tan(phi)*tan(phi);
double tan4Phi = tan2Phi*tan2Phi;
double cos3Phi = cos(phi) * cos(phi) * cos(phi);
double cos5Phi = cos3Phi * cos(phi) * cos(phi);
double tan2Phi = tan(phi) * tan(phi);
double tan4Phi = tan2Phi * tan2Phi;
double I = m + n0;
double II = (v/2)*sin(phi)*cos(phi);
double III = (v/24)*sin(phi)*cos3Phi*(5 - tan2Phi + 9*eta2);
double IIIA = (v/720)*sin(phi)*cos5Phi*(61 - 58*tan2Phi + tan4Phi);
double IV = v*cos(phi);
double V = (v/6)*cos3Phi*(v/rho - tan2Phi);
double VI = (v/120)*cos5Phi*(5 - 18*tan2Phi + tan4Phi + 14*eta2 - 58*tan2Phi*eta2);
double II = (v / 2) * sin(phi) * cos(phi);
double III = (v / 24) * sin(phi) * cos3Phi * (5 - tan2Phi + 9 * eta2);
double IIIA = (v / 720) * sin(phi) * cos5Phi * (61 - 58 * tan2Phi + tan4Phi);
double IV = v * cos(phi);
double V = (v / 6) * cos3Phi * (v / rho - tan2Phi);
double VI = (v / 120) * cos5Phi * (5 - 18 * tan2Phi + tan4Phi + 14 * eta2 - 58 * tan2Phi * eta2);
double deltaLambda = lambda - lambda0;
double deltaLambda2 = deltaLambda*deltaLambda;
double northing = I + II*deltaLambda2 + III*deltaLambda2*deltaLambda2 + IIIA*deltaLambda2*deltaLambda2*deltaLambda2;
double easting = e0 + IV*deltaLambda + V*deltaLambda2*deltaLambda + VI*deltaLambda2*deltaLambda2*deltaLambda;
double deltaLambda2 = deltaLambda * deltaLambda;
double northing =
I + II * deltaLambda2 + III * deltaLambda2 * deltaLambda2 + IIIA * deltaLambda2 * deltaLambda2 * deltaLambda2;
double easting = e0 + IV * deltaLambda + V * deltaLambda2 * deltaLambda + VI * deltaLambda2 * deltaLambda2 * deltaLambda;
if (easting < 0 || easting > 700000 || northing < 0 || northing > 1300000) // Check if out of boundaries
osgr = { 'I', 'I', 0, 0 };
osgr = {'I', 'I', 0, 0};
else {
uint32_t e100k = floor(easting / 100000);
uint32_t n100k = floor(northing / 100000);
@@ -232,7 +258,8 @@ void GeoCoord::latLongToOSGR(const double lat, const double lon, OSGR &osgr) {
* Converts lat long coordinates to Open Location Code.
* Based on: https://github.com/google/open-location-code/blob/main/c/src/olc.c
*/
void GeoCoord::latLongToOLC(double lat, double lon, OLC &olc) {
void GeoCoord::latLongToOLC(double lat, double lon, OLC &olc)
{
char tempCode[] = "1234567890abc";
const char kAlphabet[] = "23456789CFGHJMPQRVWX";
double latitude;
@@ -258,7 +285,7 @@ void GeoCoord::latLongToOLC(double lat, double lon, OLC &olc) {
lat_val += latitude * 2.5e7;
lng_val += longitude * 8.192e6;
size_t pos = OLC_CODE_LEN;
if (OLC_CODE_LEN > 10) { // Compute grid part of code if needed
for (size_t i = 0; i < 5; i++) {
int lat_digit = lat_val % 5;
@@ -272,9 +299,9 @@ void GeoCoord::latLongToOLC(double lat, double lon, OLC &olc) {
lat_val /= pow(5, 5);
lng_val /= pow(4, 5);
}
pos = 10;
for (size_t i = 0; i < 5; i++) { // Compute pair section of code
int lat_ndx = lat_val % 20;
int lng_ndx = lng_val % 20;
@@ -286,7 +313,7 @@ void GeoCoord::latLongToOLC(double lat, double lon, OLC &olc) {
if (i == 0)
tempCode[pos--] = '+';
}
if (OLC_CODE_LEN < 9) { // Add padding if needed
for (size_t i = OLC_CODE_LEN; i < 9; i++)
tempCode[i] = '0';
@@ -300,50 +327,52 @@ void GeoCoord::latLongToOLC(double lat, double lon, OLC &olc) {
for (size_t i = 0; i < char_count; i++) {
olc.code[i] = tempCode[i];
}
olc.code[char_count] = '\0';
olc.code[char_count] = '\0';
}
// Converts the coordinate in WGS84 datum to the OSGB36 datum.
void GeoCoord::convertWGS84ToOSGB36(const double lat, const double lon, double &osgb_Latitude, double &osgb_Longitude) {
void GeoCoord::convertWGS84ToOSGB36(const double lat, const double lon, double &osgb_Latitude, double &osgb_Longitude)
{
// Convert lat long to cartesian
double phi = toRadians(lat);
double lambda = toRadians(lon);
double h = 0.0; // No OSTN height data used, some loss of accuracy (up to 5m)
double wgsA = 6378137; // WGS84 datum semi major axis
double h = 0.0; // No OSTN height data used, some loss of accuracy (up to 5m)
double wgsA = 6378137; // WGS84 datum semi major axis
double wgsF = 1 / 298.257223563; // WGS84 datum flattening
double ecc = 2*wgsF - wgsF*wgsF;
double ecc = 2 * wgsF - wgsF * wgsF;
double vee = wgsA / sqrt(1 - ecc * pow(sin(phi), 2));
double wgsX = (vee + h) * cos(phi) * cos(lambda);
double wgsY = (vee + h) * cos(phi) * sin(lambda);
double wgsZ = ((1 - ecc) * vee + h) * sin(phi);
// 7-parameter Helmert transform
double tx = -446.448; // x shift in meters
double ty = 125.157; // y shift in meters
double tz = -542.060; // z shift in meters
double s = 20.4894/1e6 + 1; // scale normalized parts per million to (s + 1)
double rx = toRadians(-0.1502/3600); // x rotation normalize arcseconds to radians
double ry = toRadians(-0.2470/3600); // y rotation normalize arcseconds to radians
double rz = toRadians(-0.8421/3600); // z rotation normalize arcseconds to radians
double osgbX = tx + wgsX*s - wgsY*rz + wgsZ*ry;
double osgbY = ty + wgsX*rz + wgsY*s - wgsZ*rx;
double osgbZ = tz - wgsX*ry + wgsY*rx + wgsZ*s;
double tx = -446.448; // x shift in meters
double ty = 125.157; // y shift in meters
double tz = -542.060; // z shift in meters
double s = 20.4894 / 1e6 + 1; // scale normalized parts per million to (s + 1)
double rx = toRadians(-0.1502 / 3600); // x rotation normalize arcseconds to radians
double ry = toRadians(-0.2470 / 3600); // y rotation normalize arcseconds to radians
double rz = toRadians(-0.8421 / 3600); // z rotation normalize arcseconds to radians
double osgbX = tx + wgsX * s - wgsY * rz + wgsZ * ry;
double osgbY = ty + wgsX * rz + wgsY * s - wgsZ * rx;
double osgbZ = tz - wgsX * ry + wgsY * rx + wgsZ * s;
// Convert cartesian to lat long
double airyA = 6377563.396; // Airy1830 datum semi major axis
double airyB = 6356256.909; // Airy1830 datum semi minor axis
double airyF = 1/ 299.3249646; // Airy1830 datum flattening
double airyEcc = 2*airyF - airyF*airyF;
double airyA = 6377563.396; // Airy1830 datum semi major axis
double airyB = 6356256.909; // Airy1830 datum semi minor axis
double airyF = 1 / 299.3249646; // Airy1830 datum flattening
double airyEcc = 2 * airyF - airyF * airyF;
double airyEcc2 = airyEcc / (1 - airyEcc);
double p = sqrt(osgbX*osgbX + osgbY*osgbY);
double R = sqrt(p*p + osgbZ*osgbZ);
double tanBeta = (airyB*osgbZ) / (airyA*p) * (1 + airyEcc2*airyB/R);
double sinBeta = tanBeta / sqrt(1 + tanBeta*tanBeta);
double p = sqrt(osgbX * osgbX + osgbY * osgbY);
double R = sqrt(p * p + osgbZ * osgbZ);
double tanBeta = (airyB * osgbZ) / (airyA * p) * (1 + airyEcc2 * airyB / R);
double sinBeta = tanBeta / sqrt(1 + tanBeta * tanBeta);
double cosBeta = sinBeta / tanBeta;
osgb_Latitude = atan2(osgbZ + airyEcc2*airyB*sinBeta*sinBeta*sinBeta, p - airyEcc*airyA*cosBeta*cosBeta*cosBeta); // leave in radians
osgb_Longitude = atan2(osgbY, osgbX); // leave in radians
//osgb height = p*cos(osgb.latitude) + osgbZ*sin(osgb.latitude) -
//(airyA*airyA/(airyA / sqrt(1 - airyEcc*sin(osgb.latitude)*sin(osgb.latitude)))); // Not used, no OSTN data
osgb_Latitude = atan2(osgbZ + airyEcc2 * airyB * sinBeta * sinBeta * sinBeta,
p - airyEcc * airyA * cosBeta * cosBeta * cosBeta); // leave in radians
osgb_Longitude = atan2(osgbY, osgbX); // leave in radians
// osgb height = p*cos(osgb.latitude) + osgbZ*sin(osgb.latitude) -
//(airyA*airyA/(airyA / sqrt(1 - airyEcc*sin(osgb.latitude)*sin(osgb.latitude)))); // Not used, no OSTN data
}
/// Ported from my old java code, returns distance in meters along the globe
@@ -397,12 +426,13 @@ float GeoCoord::bearing(double lat1, double lon1, double lat2, double lon2)
* @brief Convert from meters to range in radians on a great circle
* @param range_meters
* The range in meters
* @return range in radians on a great circle
* @return range in radians on a great circle
*/
float GeoCoord::rangeMetersToRadians(double range_meters) {
float GeoCoord::rangeMetersToRadians(double range_meters)
{
// 1 nm is 1852 meters
double distance_nm = range_meters * 1852;
return (PI / (180 * 60)) *distance_nm;
return (PI / (180 * 60)) * distance_nm;
}
/**
@@ -410,22 +440,27 @@ float GeoCoord::rangeMetersToRadians(double range_meters) {
* @brief Convert from radians to range in meters on a great circle
* @param range_radians
* The range in radians
* @return Range in meters on a great circle
* @return Range in meters on a great circle
*/
float GeoCoord::rangeRadiansToMeters(double range_radians) {
float GeoCoord::rangeRadiansToMeters(double range_radians)
{
double distance_nm = ((180 * 60) / PI) * range_radians;
// 1 meter is 0.000539957 nm
return distance_nm * 0.000539957;
}
// Find distance from point to passed in point
int32_t GeoCoord::distanceTo(const GeoCoord& pointB) {
return latLongToMeter(this->getLatitude() * 1e-7, this->getLongitude() * 1e-7, pointB.getLatitude() * 1e-7, pointB.getLongitude() * 1e-7);
int32_t GeoCoord::distanceTo(const GeoCoord &pointB)
{
return latLongToMeter(this->getLatitude() * 1e-7, this->getLongitude() * 1e-7, pointB.getLatitude() * 1e-7,
pointB.getLongitude() * 1e-7);
}
// Find bearing from point to passed in point
int32_t GeoCoord::bearingTo(const GeoCoord& pointB) {
return bearing(this->getLatitude() * 1e-7, this->getLongitude() * 1e-7, pointB.getLatitude() * 1e-7, pointB.getLongitude() * 1e-7);
int32_t GeoCoord::bearingTo(const GeoCoord &pointB)
{
return bearing(this->getLatitude() * 1e-7, this->getLongitude() * 1e-7, pointB.getLatitude() * 1e-7,
pointB.getLongitude() * 1e-7);
}
/**
@@ -436,8 +471,9 @@ int32_t GeoCoord::bearingTo(const GeoCoord& pointB) {
* @param range_meters
* range in meters
* @return GeoCoord object of point at bearing and range from initial point
*/
std::shared_ptr<GeoCoord> GeoCoord::pointAtDistance(double bearing, double range_meters) {
*/
std::shared_ptr<GeoCoord> GeoCoord::pointAtDistance(double bearing, double range_meters)
{
double range_radians = rangeMetersToRadians(range_meters);
double lat1 = this->getLatitude() * 1e-7;
double lon1 = this->getLongitude() * 1e-7;
@@ -446,5 +482,4 @@ std::shared_ptr<GeoCoord> GeoCoord::pointAtDistance(double bearing, double range
double lon = fmod(lon1 - dlon + PI, 2 * PI) - PI;
return std::make_shared<GeoCoord>(double(lat), double(lon), this->getAltitude());
}

View File

@@ -1,26 +1,27 @@
#pragma once
#include <algorithm>
#include <string>
#include <cstring>
#include <cstdint>
#include <cstring>
#include <math.h>
#include <stdint.h>
#include <stdexcept>
#include <memory>
#include <stdexcept>
#include <stdint.h>
#include <string>
#define PI 3.1415926535897932384626433832795
#define OLC_CODE_LEN 11
// Helper functions
// Raises a number to an exponent, handling negative exponents.
static inline double pow_neg(double base, double exponent) {
if (exponent == 0) {
return 1;
} else if (exponent > 0) {
return pow(base, exponent);
}
return 1 / pow(base, -exponent);
static inline double pow_neg(double base, double exponent)
{
if (exponent == 0) {
return 1;
} else if (exponent > 0) {
return pow(base, exponent);
}
return 1 / pow(base, -exponent);
}
static inline double toRadians(double deg)
@@ -35,8 +36,7 @@ static inline double toDegrees(double r)
// GeoCoord structs/classes
// A struct to hold the data for a DMS coordinate.
struct DMS
{
struct DMS {
uint8_t latDeg;
uint8_t latMin;
uint32_t latSec;
@@ -48,8 +48,7 @@ struct DMS
};
// A struct to hold the data for a UTM coordinate, this is also used when creating an MGRS coordinate.
struct UTM
{
struct UTM {
uint8_t zone;
char band;
uint32_t easting;
@@ -57,8 +56,7 @@ struct UTM
};
// A struct to hold the data for a MGRS coordinate.
struct MGRS
{
struct MGRS {
uint8_t zone;
char band;
char east100k;
@@ -80,85 +78,85 @@ struct OLC {
char code[OLC_CODE_LEN + 1]; // +1 for null termination
};
class GeoCoord {
private:
int32_t _latitude = 0;
int32_t _longitude = 0;
int32_t _altitude = 0;
class GeoCoord
{
private:
int32_t _latitude = 0;
int32_t _longitude = 0;
int32_t _altitude = 0;
DMS _dms = {};
UTM _utm = {};
MGRS _mgrs = {};
OSGR _osgr = {};
OLC _olc = {};
DMS _dms = {};
UTM _utm = {};
MGRS _mgrs = {};
OSGR _osgr = {};
OLC _olc = {};
bool _dirty = true;
bool _dirty = true;
void setCoords();
void setCoords();
public:
GeoCoord();
GeoCoord(int32_t lat, int32_t lon, int32_t alt);
GeoCoord(double lat, double lon, int32_t alt);
GeoCoord(float lat, float lon, int32_t alt);
public:
GeoCoord();
GeoCoord(int32_t lat, int32_t lon, int32_t alt);
GeoCoord(double lat, double lon, int32_t alt);
GeoCoord(float lat, float lon, int32_t alt);
void updateCoords(const int32_t lat, const int32_t lon, const int32_t alt);
void updateCoords(const double lat, const double lon, const int32_t alt);
void updateCoords(const float lat, const float lon, const int32_t alt);
void updateCoords(const int32_t lat, const int32_t lon, const int32_t alt);
void updateCoords(const double lat, const double lon, const int32_t alt);
void updateCoords(const float lat, const float lon, const int32_t alt);
// Conversions
static void latLongToDMS(const double lat, const double lon, DMS &dms);
static void latLongToUTM(const double lat, const double lon, UTM &utm);
static void latLongToMGRS(const double lat, const double lon, MGRS &mgrs);
static void latLongToOSGR(const double lat, const double lon, OSGR &osgr);
static void latLongToOLC(const double lat, const double lon, OLC &olc);
static void convertWGS84ToOSGB36(const double lat, const double lon, double &osgb_Latitude, double &osgb_Longitude);
static float latLongToMeter(double lat_a, double lng_a, double lat_b, double lng_b);
static float bearing(double lat1, double lon1, double lat2, double lon2);
static float rangeRadiansToMeters(double range_radians);
static float rangeMetersToRadians(double range_meters);
// Conversions
static void latLongToDMS(const double lat, const double lon, DMS &dms);
static void latLongToUTM(const double lat, const double lon, UTM &utm);
static void latLongToMGRS(const double lat, const double lon, MGRS &mgrs);
static void latLongToOSGR(const double lat, const double lon, OSGR &osgr);
static void latLongToOLC(const double lat, const double lon, OLC &olc);
static void convertWGS84ToOSGB36(const double lat, const double lon, double &osgb_Latitude, double &osgb_Longitude);
static float latLongToMeter(double lat_a, double lng_a, double lat_b, double lng_b);
static float bearing(double lat1, double lon1, double lat2, double lon2);
static float rangeRadiansToMeters(double range_radians);
static float rangeMetersToRadians(double range_meters);
// Point to point conversions
int32_t distanceTo(const GeoCoord& pointB);
int32_t bearingTo(const GeoCoord& pointB);
std::shared_ptr<GeoCoord> pointAtDistance(double bearing, double range);
// Point to point conversions
int32_t distanceTo(const GeoCoord &pointB);
int32_t bearingTo(const GeoCoord &pointB);
std::shared_ptr<GeoCoord> pointAtDistance(double bearing, double range);
// Lat lon alt getters
int32_t getLatitude() const { return _latitude; }
int32_t getLongitude() const { return _longitude; }
int32_t getAltitude() const { return _altitude; }
// Lat lon alt getters
int32_t getLatitude() const { return _latitude; }
int32_t getLongitude() const { return _longitude; }
int32_t getAltitude() const { return _altitude; }
// DMS getters
uint8_t getDMSLatDeg() const { return _dms.latDeg; }
uint8_t getDMSLatMin() const { return _dms.latMin; }
uint32_t getDMSLatSec() const { return _dms.latSec; }
char getDMSLatCP() const { return _dms.latCP; }
uint8_t getDMSLonDeg() const { return _dms.lonDeg; }
uint8_t getDMSLonMin() const { return _dms.lonMin; }
uint32_t getDMSLonSec() const { return _dms.lonSec; }
char getDMSLonCP() const { return _dms.lonCP; }
// DMS getters
uint8_t getDMSLatDeg() const { return _dms.latDeg; }
uint8_t getDMSLatMin() const { return _dms.latMin; }
uint32_t getDMSLatSec() const { return _dms.latSec; }
char getDMSLatCP() const { return _dms.latCP; }
uint8_t getDMSLonDeg() const { return _dms.lonDeg; }
uint8_t getDMSLonMin() const { return _dms.lonMin; }
uint32_t getDMSLonSec() const { return _dms.lonSec; }
char getDMSLonCP() const { return _dms.lonCP; }
// UTM getters
uint8_t getUTMZone() const { return _utm.zone; }
char getUTMBand() const { return _utm.band; }
uint32_t getUTMEasting() const { return _utm.easting; }
uint32_t getUTMNorthing() const { return _utm.northing; }
// UTM getters
uint8_t getUTMZone() const { return _utm.zone; }
char getUTMBand() const { return _utm.band; }
uint32_t getUTMEasting() const { return _utm.easting; }
uint32_t getUTMNorthing() const { return _utm.northing; }
// MGRS getters
uint8_t getMGRSZone() const { return _mgrs.zone; }
char getMGRSBand() const { return _mgrs.band; }
char getMGRSEast100k() const { return _mgrs.east100k; }
char getMGRSNorth100k() const { return _mgrs.north100k; }
uint32_t getMGRSEasting() const { return _mgrs.easting; }
uint32_t getMGRSNorthing() const { return _mgrs.northing; }
// MGRS getters
uint8_t getMGRSZone() const { return _mgrs.zone; }
char getMGRSBand() const { return _mgrs.band; }
char getMGRSEast100k() const { return _mgrs.east100k; }
char getMGRSNorth100k() const { return _mgrs.north100k; }
uint32_t getMGRSEasting() const { return _mgrs.easting; }
uint32_t getMGRSNorthing() const { return _mgrs.northing; }
// OSGR getters
char getOSGRE100k() const { return _osgr.e100k; }
char getOSGRN100k() const { return _osgr.n100k; }
uint32_t getOSGREasting() const { return _osgr.easting; }
uint32_t getOSGRNorthing() const { return _osgr.northing; }
// OSGR getters
char getOSGRE100k() const { return _osgr.e100k; }
char getOSGRN100k() const { return _osgr.n100k; }
uint32_t getOSGREasting() const { return _osgr.easting; }
uint32_t getOSGRNorthing() const { return _osgr.northing; }
// OLC getter
void getOLCCode(char* code) { strncpy(code, _olc.code, OLC_CODE_LEN + 1); } // +1 for null termination
// OLC getter
void getOLCCode(char *code) { strncpy(code, _olc.code, OLC_CODE_LEN + 1); } // +1 for null termination
};

View File

@@ -1,12 +1,12 @@
#include "configuration.h"
#include "NMEAGPS.h"
#include "RTC.h"
#include "configuration.h"
#include <TinyGPS++.h>
// GPS solutions older than this will be rejected - see TinyGPSDatum::age()
#define GPS_SOL_EXPIRY_MS 5000 // in millis. give 1 second time to combine different sentences. NMEA Frequency isn't higher anyway
#define NMEA_MSG_GXGSA "GNGSA" // GSA message (GPGSA, GNGSA etc)
#define GPS_SOL_EXPIRY_MS 5000 // in millis. give 1 second time to combine different sentences. NMEA Frequency isn't higher anyway
#define NMEA_MSG_GXGSA "GNGSA" // GSA message (GPGSA, GNGSA etc)
static int32_t toDegInt(RawDegrees d)
{
@@ -20,19 +20,18 @@ static int32_t toDegInt(RawDegrees d)
bool NMEAGPS::factoryReset()
{
#ifdef PIN_GPS_REINIT
//The L76K GNSS on the T-Echo requires the RESET pin to be pulled LOW
// The L76K GNSS on the T-Echo requires the RESET pin to be pulled LOW
digitalWrite(PIN_GPS_REINIT, 0);
pinMode(PIN_GPS_REINIT, OUTPUT);
delay(150); //The L76K datasheet calls for at least 100MS delay
delay(150); // The L76K datasheet calls for at least 100MS delay
digitalWrite(PIN_GPS_REINIT, 1);
#endif
#endif
// send the UBLOX Factory Reset Command regardless of detect state, something is very wrong, just assume it's UBLOX.
// Factory Reset
byte _message_reset[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF,
0xFB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0x00, 0x00, 0x17, 0x2B, 0x7E};
_serial_gps->write(_message_reset,sizeof(_message_reset));
byte _message_reset[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF, 0xFB, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x17, 0x2B, 0x7E};
_serial_gps->write(_message_reset, sizeof(_message_reset));
delay(1000);
return true;
}
@@ -40,7 +39,7 @@ bool NMEAGPS::factoryReset()
bool NMEAGPS::setupGPS()
{
GPS::setupGPS();
#ifdef PIN_GPS_PPS
// pulse per second
// FIXME - move into shared GPS code
@@ -84,8 +83,9 @@ The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of s
t.tm_mon = d.month() - 1;
t.tm_year = d.year() - 1900;
t.tm_isdst = false;
if (t.tm_mon > -1){
LOG_DEBUG("NMEA GPS time %02d-%02d-%02d %02d:%02d:%02d\n", d.year(), d.month(), t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
if (t.tm_mon > -1) {
LOG_DEBUG("NMEA GPS time %02d-%02d-%02d %02d:%02d:%02d\n", d.year(), d.month(), t.tm_mday, t.tm_hour, t.tm_min,
t.tm_sec);
perhapsSetRTC(RTCQualityGPS, t);
return true;
} else
@@ -102,47 +102,44 @@ The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of s
*/
bool NMEAGPS::lookForLocation()
{
// By default, TinyGPS++ does not parse GPGSA lines, which give us
// By default, TinyGPS++ does not parse GPGSA lines, which give us
// the 2D/3D fixType (see NMEAGPS.h)
// At a minimum, use the fixQuality indicator in GPGGA (FIXME?)
fixQual = reader.fixQuality();
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
fixType = atoi(gsafixtype.value()); // will set to zero if no data
fixType = atoi(gsafixtype.value()); // will set to zero if no data
// LOG_DEBUG("FIX QUAL=%d, TYPE=%d\n", fixQual, fixType);
#endif
// check if GPS has an acceptable lock
if (! hasLock())
if (!hasLock())
return false;
#ifdef GPS_EXTRAVERBOSE
LOG_DEBUG("AGE: LOC=%d FIX=%d DATE=%d TIME=%d\n",
reader.location.age(),
LOG_DEBUG("AGE: LOC=%d FIX=%d DATE=%d TIME=%d\n", reader.location.age(),
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
gsafixtype.age(),
gsafixtype.age(),
#else
0,
0,
#endif
reader.date.age(), reader.time.age());
#endif // GPS_EXTRAVERBOSE
reader.date.age(), reader.time.age());
#endif // GPS_EXTRAVERBOSE
// check if a complete GPS solution set is available for reading
// tinyGPSDatum::age() also includes isValid() test
// FIXME
if (! ((reader.location.age() < GPS_SOL_EXPIRY_MS) &&
if (!((reader.location.age() < GPS_SOL_EXPIRY_MS) &&
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
(gsafixtype.age() < GPS_SOL_EXPIRY_MS) &&
(gsafixtype.age() < GPS_SOL_EXPIRY_MS) &&
#endif
(reader.time.age() < GPS_SOL_EXPIRY_MS) &&
(reader.date.age() < GPS_SOL_EXPIRY_MS)))
{
(reader.time.age() < GPS_SOL_EXPIRY_MS) && (reader.date.age() < GPS_SOL_EXPIRY_MS))) {
LOG_WARN("SOME data is TOO OLD: LOC %u, TIME %u, DATE %u\n", reader.location.age(), reader.time.age(), reader.date.age());
return false;
}
// Is this a new point or are we re-reading the previous one?
if (! reader.location.isUpdated())
if (!reader.location.isUpdated())
return false;
// We know the solution is fresh and valid, so just read the data
@@ -150,19 +147,19 @@ bool NMEAGPS::lookForLocation()
// Bail out EARLY to avoid overwriting previous good data (like #857)
if (toDegInt(loc.lat) > 900000000) {
#ifdef GPS_EXTRAVERBOSE
LOG_DEBUG("Bail out EARLY on LAT %i\n",toDegInt(loc.lat));
#ifdef GPS_EXTRAVERBOSE
LOG_DEBUG("Bail out EARLY on LAT %i\n", toDegInt(loc.lat));
#endif
return false;
}
if (toDegInt(loc.lng) > 1800000000) {
#ifdef GPS_EXTRAVERBOSE
LOG_DEBUG("Bail out EARLY on LNG %i\n",toDegInt(loc.lng));
#ifdef GPS_EXTRAVERBOSE
LOG_DEBUG("Bail out EARLY on LNG %i\n", toDegInt(loc.lng));
#endif
return false;
}
p.location_source = Position_LocSource_LOC_INTERNAL;
p.location_source = meshtastic_Position_LocSource_LOC_INTERNAL;
// Dilution of precision (an accuracy metric) is reported in 10^2 units, so we need to scale down when we use it
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
@@ -209,11 +206,11 @@ bool NMEAGPS::lookForLocation()
}
if (reader.course.isUpdated() && reader.course.isValid()) {
if (reader.course.value() < 36000) { // sanity check
p.ground_track = reader.course.value() * 1e3; // Scale the heading (in degrees * 10^-2) to match the expected degrees * 10^-5
if (reader.course.value() < 36000) { // sanity check
p.ground_track =
reader.course.value() * 1e3; // Scale the heading (in degrees * 10^-2) to match the expected degrees * 10^-5
} else {
LOG_WARN("BOGUS course.value() REJECTED: %d\n",
reader.course.value());
LOG_WARN("BOGUS course.value() REJECTED: %d\n", reader.course.value());
}
}
@@ -224,14 +221,13 @@ bool NMEAGPS::lookForLocation()
return true;
}
bool NMEAGPS::hasLock()
{
// Using GPGGA fix quality indicator
if (fixQual >= 1 && fixQual <= 5) {
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
// Use GPGSA fix type 2D/3D (better) if available
if (fixType == 3 || fixType == 0) // zero means "no data received"
if (fixType == 3 || fixType == 0) // zero means "no data received"
#endif
return true;
}

View File

@@ -12,14 +12,14 @@
class NMEAGPS : public GPS
{
TinyGPSPlus reader;
uint8_t fixQual = 0; // fix quality from GPGGA
uint8_t fixQual = 0; // fix quality from GPGGA
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
// (20210908) TinyGps++ can only read the GPGSA "FIX TYPE" field
// via optional feature "custom fields", currently disabled (bug #525)
TinyGPSCustom gsafixtype; // custom extract fix type from GPGSA
TinyGPSCustom gsapdop; // custom extract PDOP from GPGSA
uint8_t fixType = 0; // fix type from GPGSA
TinyGPSCustom gsafixtype; // custom extract fix type from GPGSA
TinyGPSCustom gsapdop; // custom extract PDOP from GPGSA
uint8_t fixType = 0; // fix type from GPGSA
#endif
public:
@@ -29,9 +29,9 @@ class NMEAGPS : public GPS
protected:
/** Subclasses should look for serial rx characters here and feed it to their GPS parser
*
*
* Return true if we received a valid message from the GPS
*/
*/
virtual bool whileIdle() override;
/**

View File

@@ -16,22 +16,18 @@
* -------------------------------------------
*/
uint32_t printWPL(char *buf, const Position &pos, const char *name)
uint32_t printWPL(char *buf, size_t bufsz, const meshtastic_Position &pos, const char *name)
{
GeoCoord geoCoord(pos.latitude_i,pos.longitude_i,pos.altitude);
uint32_t len = sprintf(buf, "$GNWPL,%02d%07.4f,%c,%03d%07.4f,%c,%s",
geoCoord.getDMSLatDeg(),
(abs(geoCoord.getLatitude()) - geoCoord.getDMSLatDeg() * 1e+7) * 6e-6,
geoCoord.getDMSLatCP(),
geoCoord.getDMSLonDeg(),
(abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6,
geoCoord.getDMSLonCP(),
name);
GeoCoord geoCoord(pos.latitude_i, pos.longitude_i, pos.altitude);
uint32_t len = snprintf(buf, bufsz, "$GNWPL,%02d%07.4f,%c,%03d%07.4f,%c,%s", geoCoord.getDMSLatDeg(),
(abs(geoCoord.getLatitude()) - geoCoord.getDMSLatDeg() * 1e+7) * 6e-6, geoCoord.getDMSLatCP(),
geoCoord.getDMSLonDeg(), (abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6,
geoCoord.getDMSLonCP(), name);
uint32_t chk = 0;
for (uint32_t i = 1; i < len; i++) {
chk ^= buf[i];
}
len += sprintf(buf + len, "*%02X\r\n", chk);
len += snprintf(buf + len, bufsz - len, "*%02X\r\n", chk);
return len;
}
@@ -51,40 +47,26 @@ uint32_t printWPL(char *buf, const Position &pos, const char *name)
* 8 Horizontal Dilution of precision (meters)
* 9 Antenna Altitude above/below mean-sea-level (geoid) (in meters)
* 10 Units of antenna altitude, meters
* 11 Geoidal separation, the difference between the WGS-84 earth ellipsoid and mean-sea-level (geoid), "-" means mean-sea-level below ellipsoid
* 12 Units of geoidal separation, meters
* 13 Age of differential GPS data, time in seconds since last SC104 type 1 or 9 update, null field when DGPS is not used
* 14 Differential reference station ID, 0000-1023
* 15 Checksum
* 11 Geoidal separation, the difference between the WGS-84 earth ellipsoid and mean-sea-level (geoid), "-" means mean-sea-level
* below ellipsoid 12 Units of geoidal separation, meters 13 Age of differential GPS data, time in seconds since last SC104 type 1
* or 9 update, null field when DGPS is not used 14 Differential reference station ID, 0000-1023 15 Checksum
* -------------------------------------------
*/
uint32_t printGGA(char *buf, const Position &pos)
uint32_t printGGA(char *buf, size_t bufsz, const meshtastic_Position &pos)
{
GeoCoord geoCoord(pos.latitude_i,pos.longitude_i,pos.altitude);
uint32_t len = sprintf(buf, "$GNGGA,%06u.%03u,%02d%07.4f,%c,%03d%07.4f,%c,%u,%02u,%04u,%04d,%c,%04d,%c,%d,%04d",
pos.time / 1000,
pos.time % 1000,
geoCoord.getDMSLatDeg(),
(abs(geoCoord.getLatitude()) - geoCoord.getDMSLatDeg() * 1e+7) * 6e-6,
geoCoord.getDMSLatCP(),
geoCoord.getDMSLonDeg(),
(abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6,
geoCoord.getDMSLonCP(),
pos.fix_type,
pos.sats_in_view,
pos.HDOP,
geoCoord.getAltitude(),
'M',
pos.altitude_geoidal_separation,
'M',
0,
0);
GeoCoord geoCoord(pos.latitude_i, pos.longitude_i, pos.altitude);
uint32_t len =
snprintf(buf, bufsz, "$GNGGA,%06u.%03u,%02d%07.4f,%c,%03d%07.4f,%c,%u,%02u,%04u,%04d,%c,%04d,%c,%d,%04d", pos.time / 1000,
pos.time % 1000, geoCoord.getDMSLatDeg(), (abs(geoCoord.getLatitude()) - geoCoord.getDMSLatDeg() * 1e+7) * 6e-6,
geoCoord.getDMSLatCP(), geoCoord.getDMSLonDeg(),
(abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6, geoCoord.getDMSLonCP(), pos.fix_type,
pos.sats_in_view, pos.HDOP, geoCoord.getAltitude(), 'M', pos.altitude_geoidal_separation, 'M', 0, 0);
uint32_t chk = 0;
for (uint32_t i = 1; i < len; i++) {
chk ^= buf[i];
}
len += sprintf(buf + len, "*%02X\r\n", chk);
len += snprintf(buf + len, bufsz - len, "*%02X\r\n", chk);
return len;
}

View File

@@ -1,7 +1,7 @@
#pragma once
#include <Arduino.h>
#include "main.h"
#include <Arduino.h>
uint32_t printWPL(char *buf, const Position &pos, const char *name);
uint32_t printGGA(char *buf, const Position &pos);
uint32_t printWPL(char *buf, size_t bufsz, const meshtastic_Position &pos, const char *name);
uint32_t printGGA(char *buf, size_t bufsz, const meshtastic_Position &pos);

View File

@@ -20,7 +20,7 @@ void readFromRTC()
{
struct timeval tv; /* btw settimeofday() is helpfull here too*/
#ifdef RV3028_RTC
if(rtc_found == RV3028_RTC) {
if (rtc_found == RV3028_RTC) {
uint32_t now = millis();
Melopero_RV3028 rtc;
rtc.initI2C();
@@ -41,7 +41,7 @@ void readFromRTC()
}
}
#elif defined(PCF8563_RTC)
if(rtc_found == PCF8563_RTC) {
if (rtc_found == PCF8563_RTC) {
uint32_t now = millis();
PCF8563_Class rtc;
#ifdef RTC_USE_WIRE1
@@ -66,7 +66,7 @@ void readFromRTC()
currentQuality = RTCQualityDevice;
}
}
#else
#else
if (!gettimeofday(&tv, NULL)) {
uint32_t now = millis();
LOG_DEBUG("Read RTC time as %ld\n", tv.tv_sec);
@@ -87,12 +87,11 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
currentQuality = q;
shouldSet = true;
LOG_DEBUG("Upgrading time to RTC %ld secs (quality %d)\n", tv->tv_sec, q);
} else if(q == RTCQualityGPS && (now - lastSetMsec) > (12 * 60 * 60 * 1000UL)) {
} else if (q == RTCQualityGPS && (now - lastSetMsec) > (12 * 60 * 60 * 1000UL)) {
// Every 12 hrs we will slam in a new GPS time, to correct for local RTC clock drift
shouldSet = true;
LOG_DEBUG("Reapplying external time to correct clock drift %ld secs\n", tv->tv_sec);
}
else
} else
shouldSet = false;
if (shouldSet) {
@@ -104,24 +103,26 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
// If this platform has a setable RTC, set it
#ifdef RV3028_RTC
if(rtc_found == RV3028_RTC) {
if (rtc_found == RV3028_RTC) {
Melopero_RV3028 rtc;
rtc.initI2C();
tm *t = localtime(&tv->tv_sec);
rtc.setTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_wday, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
LOG_DEBUG("RV3028_RTC setTime %02d-%02d-%02d %02d:%02d:%02d %ld\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, tv->tv_sec);
LOG_DEBUG("RV3028_RTC setTime %02d-%02d-%02d %02d:%02d:%02d %ld\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
t->tm_hour, t->tm_min, t->tm_sec, tv->tv_sec);
}
#elif defined(PCF8563_RTC)
if(rtc_found == PCF8563_RTC) {
if (rtc_found == PCF8563_RTC) {
PCF8563_Class rtc;
#ifdef RTC_USE_WIRE1
rtc.begin(Wire1);
rtc.begin(Wire1);
#else
rtc.begin();
rtc.begin();
#endif
tm *t = localtime(&tv->tv_sec);
rtc.setDateTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
LOG_DEBUG("PCF8563_RTC setDateTime %02d-%02d-%02d %02d:%02d:%02d %ld\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, tv->tv_sec);
LOG_DEBUG("PCF8563_RTC setDateTime %02d-%02d-%02d %02d:%02d:%02d %ld\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
t->tm_hour, t->tm_min, t->tm_sec, tv->tv_sec);
}
#elif defined(ARCH_ESP32)
settimeofday(tv, NULL);
@@ -160,7 +161,7 @@ bool perhapsSetRTC(RTCQuality q, struct tm &t)
uint32_t getTime()
{
return (((uint32_t) millis() - timeStartMsec) / 1000) + zeroOffsetSecs;
return (((uint32_t)millis() - timeStartMsec) / 1000) + zeroOffsetSecs;
}
uint32_t getValidTime(RTCQuality minQuality)

View File

@@ -1,11 +1,11 @@
#include "configuration.h"
#ifdef USE_EINK
#include "main.h"
#include "EInkDisplay2.h"
#include "SPILock.h"
#include <SPI.h>
#include "GxEPD2_BW.h"
#include "SPILock.h"
#include "main.h"
#include <SPI.h>
#define COLORED GxEPD_BLACK
#define UNCOLORED GxEPD_WHITE
@@ -14,62 +14,63 @@
#define TECHO_DISPLAY_MODEL GxEPD2_154_D67
#elif defined(RAK4630)
//GxEPD2_213_BN - RAK14000 2.13 inch b/w 250x122 - changed from GxEPD2_213_B74 - which was not going to give partial update support
// GxEPD2_213_BN - RAK14000 2.13 inch b/w 250x122 - changed from GxEPD2_213_B74 - which was not going to give partial update
// support
#define TECHO_DISPLAY_MODEL GxEPD2_213_BN
//4.2 inch 300x400 - GxEPD2_420_M01
// 4.2 inch 300x400 - GxEPD2_420_M01
//#define TECHO_DISPLAY_MODEL GxEPD2_420_M01
//2.9 inch 296x128 - GxEPD2_290_T5D
// 2.9 inch 296x128 - GxEPD2_290_T5D
//#define TECHO_DISPLAY_MODEL GxEPD2_290_T5D
//1.54 inch 200x200 - GxEPD2_154_M09
// 1.54 inch 200x200 - GxEPD2_154_M09
//#define TECHO_DISPLAY_MODEL GxEPD2_154_M09
#elif defined(PCA10059)
//4.2 inch 300x400 - GxEPD2_420_M01
// 4.2 inch 300x400 - GxEPD2_420_M01
#define TECHO_DISPLAY_MODEL GxEPD2_420_M01
#elif defined(M5_COREINK)
//M5Stack CoreInk
//1.54 inch 200x200 - GxEPD2_154_M09
// M5Stack CoreInk
// 1.54 inch 200x200 - GxEPD2_154_M09
#define TECHO_DISPLAY_MODEL GxEPD2_154_M09
#endif
GxEPD2_BW<TECHO_DISPLAY_MODEL, TECHO_DISPLAY_MODEL::HEIGHT> *adafruitDisplay;
EInkDisplay::EInkDisplay(uint8_t address, int sda, int scl)
EInkDisplay::EInkDisplay(uint8_t address, int sda, int scl, uint8_t screen_model)
{
#if defined(TTGO_T_ECHO)
#if defined(TTGO_T_ECHO)
setGeometry(GEOMETRY_RAWMODE, TECHO_DISPLAY_MODEL::WIDTH, TECHO_DISPLAY_MODEL::HEIGHT);
#elif defined(RAK4630)
//GxEPD2_213_BN - RAK14000 2.13 inch b/w 250x122
#elif defined(RAK4630)
// GxEPD2_213_BN - RAK14000 2.13 inch b/w 250x122
setGeometry(GEOMETRY_RAWMODE, 250, 122);
//GxEPD2_420_M01
//setGeometry(GEOMETRY_RAWMODE, 300, 400);
// GxEPD2_420_M01
// setGeometry(GEOMETRY_RAWMODE, 300, 400);
//GxEPD2_290_T5D
//setGeometry(GEOMETRY_RAWMODE, 296, 128);
// GxEPD2_290_T5D
// setGeometry(GEOMETRY_RAWMODE, 296, 128);
//GxEPD2_154_M09
//setGeometry(GEOMETRY_RAWMODE, 200, 200);
#elif defined(PCA10059)
// GxEPD2_154_M09
// setGeometry(GEOMETRY_RAWMODE, 200, 200);
//GxEPD2_420_M01
#elif defined(PCA10059)
// GxEPD2_420_M01
setGeometry(GEOMETRY_RAWMODE, 300, 400);
#elif defined(M5_COREINK)
//M5Stack_CoreInk 200x200
//1.54 inch 200x200 - GxEPD2_154_M09
#elif defined(M5_COREINK)
// M5Stack_CoreInk 200x200
// 1.54 inch 200x200 - GxEPD2_154_M09
setGeometry(GEOMETRY_RAWMODE, EPD_HEIGHT, EPD_WIDTH);
#endif
#endif
// setGeometry(GEOMETRY_RAWMODE, 128, 64); // old resolution
// setGeometry(GEOMETRY_128_64); // We originally used this because I wasn't sure if rawmode worked - it does
}
@@ -104,28 +105,28 @@ bool EInkDisplay::forceDisplay(uint32_t msecLimit)
}
LOG_DEBUG("Updating E-Paper... ");
#if defined(TTGO_T_ECHO)
#if defined(TTGO_T_ECHO)
// ePaper.Reset(); // wake the screen from sleep
adafruitDisplay->display(false); // FIXME, use partial update mode
#elif defined(RAK4630)
//RAK14000 2.13 inch b/w 250x122 actually now does support partial updates
//Full update mode (slow)
//adafruitDisplay->display(false); // FIXME, use partial update mode
//Only enable for e-Paper with support for partial updates and comment out above adafruitDisplay->display(false);
// 1.54 inch 200x200 - GxEPD2_154_M09
// 2.13 inch 250x122 - GxEPD2_213_BN
// 2.9 inch 296x128 - GxEPD2_290_T5D
// 4.2 inch 300x400 - GxEPD2_420_M01
#elif defined(RAK4630)
// RAK14000 2.13 inch b/w 250x122 actually now does support partial updates
// Full update mode (slow)
// adafruitDisplay->display(false); // FIXME, use partial update mode
// Only enable for e-Paper with support for partial updates and comment out above adafruitDisplay->display(false);
// 1.54 inch 200x200 - GxEPD2_154_M09
// 2.13 inch 250x122 - GxEPD2_213_BN
// 2.9 inch 296x128 - GxEPD2_290_T5D
// 4.2 inch 300x400 - GxEPD2_420_M01
adafruitDisplay->nextPage();
#elif defined(PCA10059) || defined(M5_COREINK)
#elif defined(PCA10059) || defined(M5_COREINK)
adafruitDisplay->nextPage();
#endif
#endif
// Put screen to sleep to save power (possibly not necessary because we already did poweroff inside of display)
adafruitDisplay->hibernate();
LOG_DEBUG("done\n");
@@ -175,41 +176,40 @@ bool EInkDisplay::connect()
pinMode(PIN_EINK_EN, OUTPUT);
#endif
#if defined(TTGO_T_ECHO)
{
auto lowLevel = new TECHO_DISPLAY_MODEL(PIN_EINK_CS, PIN_EINK_DC, PIN_EINK_RES, PIN_EINK_BUSY, SPI1);
adafruitDisplay = new GxEPD2_BW<TECHO_DISPLAY_MODEL, TECHO_DISPLAY_MODEL::HEIGHT>(*lowLevel);
adafruitDisplay->init();
adafruitDisplay->setRotation(3);
}
#elif defined(RAK4630)
{
if (eink_found) {
auto lowLevel = new TECHO_DISPLAY_MODEL(PIN_EINK_CS, PIN_EINK_DC, PIN_EINK_RES, PIN_EINK_BUSY);
{
auto lowLevel = new TECHO_DISPLAY_MODEL(PIN_EINK_CS, PIN_EINK_DC, PIN_EINK_RES, PIN_EINK_BUSY, SPI1);
adafruitDisplay = new GxEPD2_BW<TECHO_DISPLAY_MODEL, TECHO_DISPLAY_MODEL::HEIGHT>(*lowLevel);
adafruitDisplay->init(115200, true, 10, false, SPI1, SPISettings(4000000, MSBFIRST, SPI_MODE0));
//RAK14000 2.13 inch b/w 250x122 does actually now support partial updates
adafruitDisplay->init();
adafruitDisplay->setRotation(3);
//Partial update support for 1.54, 2.13 RAK14000 b/w , 2.9 and 4.2
//adafruitDisplay->setRotation(1);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
} else {
(void)adafruitDisplay;
}
}
}
#elif defined(RAK4630)
{
if (eink_found) {
auto lowLevel = new TECHO_DISPLAY_MODEL(PIN_EINK_CS, PIN_EINK_DC, PIN_EINK_RES, PIN_EINK_BUSY);
adafruitDisplay = new GxEPD2_BW<TECHO_DISPLAY_MODEL, TECHO_DISPLAY_MODEL::HEIGHT>(*lowLevel);
adafruitDisplay->init(115200, true, 10, false, SPI1, SPISettings(4000000, MSBFIRST, SPI_MODE0));
// RAK14000 2.13 inch b/w 250x122 does actually now support partial updates
adafruitDisplay->setRotation(3);
// Partial update support for 1.54, 2.13 RAK14000 b/w , 2.9 and 4.2
// adafruitDisplay->setRotation(1);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
} else {
(void)adafruitDisplay;
}
}
#elif defined(PCA10059)
{
auto lowLevel = new TECHO_DISPLAY_MODEL(PIN_EINK_CS, PIN_EINK_DC, PIN_EINK_RES, PIN_EINK_BUSY);
adafruitDisplay = new GxEPD2_BW<TECHO_DISPLAY_MODEL, TECHO_DISPLAY_MODEL::HEIGHT>(*lowLevel);
adafruitDisplay->init(115200, true, 10, false, SPI1, SPISettings(4000000, MSBFIRST, SPI_MODE0));
adafruitDisplay->setRotation(3);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
}
{
auto lowLevel = new TECHO_DISPLAY_MODEL(PIN_EINK_CS, PIN_EINK_DC, PIN_EINK_RES, PIN_EINK_BUSY);
adafruitDisplay = new GxEPD2_BW<TECHO_DISPLAY_MODEL, TECHO_DISPLAY_MODEL::HEIGHT>(*lowLevel);
adafruitDisplay->init(115200, true, 10, false, SPI1, SPISettings(4000000, MSBFIRST, SPI_MODE0));
adafruitDisplay->setRotation(3);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
}
#elif defined(M5_COREINK)
auto lowLevel = new TECHO_DISPLAY_MODEL(PIN_EINK_CS, PIN_EINK_DC, PIN_EINK_RES, PIN_EINK_BUSY);
adafruitDisplay = new GxEPD2_BW<TECHO_DISPLAY_MODEL, TECHO_DISPLAY_MODEL::HEIGHT>(*lowLevel);
@@ -217,12 +217,11 @@ bool EInkDisplay::connect()
adafruitDisplay->setRotation(0);
adafruitDisplay->setPartialWindow(0, 0, EPD_WIDTH, EPD_HEIGHT);
#endif
//adafruitDisplay->setFullWindow();
//adafruitDisplay->fillScreen(UNCOLORED);
//adafruitDisplay->drawCircle(100, 100, 20, COLORED);
//adafruitDisplay->display(false);
// adafruitDisplay->setFullWindow();
// adafruitDisplay->fillScreen(UNCOLORED);
// adafruitDisplay->drawCircle(100, 100, 20, COLORED);
// adafruitDisplay->display(false);
return true;
}

View File

@@ -17,26 +17,26 @@ class EInkDisplay : public OLEDDisplay
/// How often should we update the display
/// thereafter we do once per 5 minutes
uint32_t slowUpdateMsec = 5 * 60 * 1000;
public:
/* constructor
FIXME - the parameters are not used, just a temporary hack to keep working like the old displays
*/
EInkDisplay(uint8_t address, int sda, int scl);
EInkDisplay(uint8_t address, int sda, int scl, uint8_t screen_model);
// Write the buffer to the display memory (for eink we only do this occasionally)
virtual void display(void) override;
/**
* Force a display update if we haven't drawn within the specified msecLimit
*
*
* @return true if we did draw the screen
*/
bool forceDisplay(uint32_t msecLimit = 1000);
/**
* shim to make the abstraction happy
*
*
*/
void setDetected(uint8_t detected);
@@ -50,5 +50,3 @@ class EInkDisplay : public OLEDDisplay
// Connect to the display
virtual bool connect() override;
};

View File

@@ -33,9 +33,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "main.h"
#include "mesh-pb-constants.h"
#include "mesh/Channels.h"
#include "mesh/generated/deviceonly.pb.h"
#include "modules/TextMessageModule.h"
#include "mesh/generated/meshtastic/deviceonly.pb.h"
#include "modules/ExternalNotificationModule.h"
#include "modules/TextMessageModule.h"
#include "sleep.h"
#include "target_specific.h"
#include "utils.h"
@@ -50,6 +50,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "fonts/OLEDDisplayFontsRU.h"
#endif
#ifdef OLED_UA
#include "fonts/OLEDDisplayFontsUA.h"
#endif
using namespace meshtastic; /** @todo remove */
namespace graphics
@@ -69,7 +73,9 @@ static uint32_t targetFramerate = IDLE_FRAMERATE;
static char btPIN[16] = "888888";
uint32_t logo_timeout = 5000; // 4 seconds for EACH logo
uint32_t hours_in_month = 730;
// This image definition is here instead of images.h because it's modified dynamically by the drawBattery function
uint8_t imgBattery[16] = {0xFF, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0xE7, 0x3C};
@@ -97,17 +103,21 @@ static uint16_t displayWidth, displayHeight;
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS)
// The screen is bigger so use bigger fonts
#define FONT_SMALL ArialMT_Plain_16 // Height: 19
#define FONT_SMALL ArialMT_Plain_16 // Height: 19
#define FONT_MEDIUM ArialMT_Plain_24 // Height: 28
#define FONT_LARGE ArialMT_Plain_24 // Height: 28
#define FONT_LARGE ArialMT_Plain_24 // Height: 28
#else
#ifdef OLED_RU
#define FONT_SMALL ArialMT_Plain_10_RU
#else
#ifdef OLED_UA
#define FONT_SMALL ArialMT_Plain_10_UA
#else
#define FONT_SMALL ArialMT_Plain_10 // Height: 13
#endif
#endif
#define FONT_MEDIUM ArialMT_Plain_16 // Height: 19
#define FONT_LARGE ArialMT_Plain_24 // Height: 28
#define FONT_LARGE ArialMT_Plain_24 // Height: 28
#endif
#define fontHeight(font) ((font)[1] + 1) // height is position 1
@@ -118,7 +128,6 @@ static uint16_t displayWidth, displayHeight;
#define getStringCenteredX(s) ((SCREEN_WIDTH - display->getStringWidth(s)) / 2)
/**
* Draw the icon with extra info printed around the corners
*/
@@ -236,7 +245,7 @@ static void drawWelcomeScreen(OLEDDisplay *display, OLEDDisplayUiState *state, i
display->drawString(64 + x, y, "//\\ E S H T /\\ S T / C");
display->drawString(64 + x, y + FONT_HEIGHT_SMALL, getDeviceName());
display->setTextAlignment(TEXT_ALIGN_LEFT);
if ((millis() / 10000) % 2) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 2 - 3, "Set the region using the");
display->drawString(x, y + FONT_HEIGHT_SMALL * 3 - 3, "Meshtastic Android, iOS,");
@@ -292,7 +301,7 @@ static void drawFrameBluetooth(OLEDDisplay *display, OLEDDisplayUiState *state,
display->drawString(x_offset + x, y_offset + y, "Bluetooth");
display->setFont(FONT_SMALL);
y_offset = display->height() == 64 ? y_offset + FONT_HEIGHT_MEDIUM -4 : y_offset + FONT_HEIGHT_MEDIUM + 5;
y_offset = display->height() == 64 ? y_offset + FONT_HEIGHT_MEDIUM - 4 : y_offset + FONT_HEIGHT_MEDIUM + 5;
display->drawString(x_offset + x, y_offset + y, "Enter this code");
display->setFont(FONT_LARGE);
@@ -302,7 +311,7 @@ static void drawFrameBluetooth(OLEDDisplay *display, OLEDDisplayUiState *state,
display->drawString(x_offset + x, y_offset + y, pin);
display->setFont(FONT_SMALL);
String deviceName = "Name: ";
String deviceName = "Name: ";
deviceName.concat(getDeviceName());
y_offset = display->height() == 64 ? y_offset + FONT_HEIGHT_LARGE - 6 : y_offset + FONT_HEIGHT_LARGE + 5;
display->drawString(x_offset + x, y_offset + y, deviceName);
@@ -332,7 +341,8 @@ static void drawFrameFirmware(OLEDDisplay *display, OLEDDisplayUiState *state, i
display->setFont(FONT_SMALL);
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->drawStringMaxWidth(0 + x, 2 + y + FONT_HEIGHT_SMALL *2, x + display->getWidth(), "Please be patient and do not power off.");
display->drawStringMaxWidth(0 + x, 2 + y + FONT_HEIGHT_SMALL * 2, x + display->getWidth(),
"Please be patient and do not power off.");
}
/// Draw the last text message we received
@@ -352,10 +362,9 @@ static void drawCriticalFaultFrame(OLEDDisplay *display, OLEDDisplayUiState *sta
}
// Ignore messages orginating from phone (from the current node 0x0) unless range test or store and forward module are enabled
static bool shouldDrawMessage(const MeshPacket *packet)
static bool shouldDrawMessage(const meshtastic_MeshPacket *packet)
{
return packet->from != 0 && !moduleConfig.range_test.enabled &&
!moduleConfig.store_forward.enabled;
return packet->from != 0 && !moduleConfig.range_test.enabled && !moduleConfig.store_forward.enabled;
}
/// Draw the last text message we received
@@ -366,8 +375,8 @@ static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state
// the max length of this buffer is much longer than we can possibly print
static char tempBuf[237];
MeshPacket &mp = devicestate.rx_text_message;
NodeInfo *node = nodeDB.getNode(getFrom(&mp));
meshtastic_MeshPacket &mp = devicestate.rx_text_message;
meshtastic_NodeInfo *node = nodeDB.getNode(getFrom(&mp));
// LOG_DEBUG("drawing text message from 0x%x: %s\n", mp.from,
// mp.decoded.variant.data.decoded.bytes);
@@ -376,14 +385,24 @@ static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state
// be wrapped. Currently only spaces and "-" are allowed for wrapping
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(FONT_SMALL);
if (config.display.displaymode == Config_DisplayConfig_DisplayMode_INVERTED) {
if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) {
display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL);
display->setColor(BLACK);
}
display->drawStringf(0 + x, 0 + y, tempBuf, "From: %s", (node && node->has_user) ? node->user.short_name : "???");
if(config.display.heading_bold) {
display->drawStringf(1 + x, 0 + y, tempBuf, "From: %s", (node && node->has_user) ? node->user.short_name : "???");
uint32_t seconds = sinceReceived(&mp);
uint32_t minutes = seconds / 60;
uint32_t hours = minutes / 60;
uint32_t days = hours / 24;
if (config.display.heading_bold) {
display->drawStringf(1 + x, 0 + y, tempBuf, "%s ago from %s",
screen->drawTimeDelta(days, hours, minutes, seconds).c_str(),
(node && node->has_user) ? node->user.short_name : "???");
}
display->drawStringf(0 + x, 0 + y, tempBuf, "%s ago from %s", screen->drawTimeDelta(days, hours, minutes, seconds).c_str(),
(node && node->has_user) ? node->user.short_name : "???");
display->setColor(WHITE);
snprintf(tempBuf, sizeof(tempBuf), "%s", mp.decoded.payload.bytes);
display->drawStringMaxWidth(0 + x, 0 + y + FONT_HEIGHT_SMALL, x + display->getWidth(), tempBuf);
@@ -412,38 +431,6 @@ static void drawColumns(OLEDDisplay *display, int16_t x, int16_t y, const char *
}
}
#if 0
/// Draw a series of fields in a row, wrapping to multiple rows if needed
/// @return the max y we ended up printing to
static uint32_t drawRows(OLEDDisplay *display, int16_t x, int16_t y, const char **fields)
{
// The coordinates define the left starting point of the text
display->setTextAlignment(TEXT_ALIGN_LEFT);
const char **f = fields;
int xo = x, yo = y;
const int COLUMNS = 2; // hardwired for two columns per row....
int col = 0; // track which column we are on
while (*f) {
display->drawString(xo, yo, *f);
xo += SCREEN_WIDTH / COLUMNS;
// Wrap to next row, if needed.
if (++col >= COLUMNS) {
xo = x;
yo += FONT_HEIGHT_SMALL;
col = 0;
}
f++;
}
if (col != 0) {
// Include last incomplete line in our total.
yo += FONT_HEIGHT_SMALL;
}
return yo;
}
#endif
// Draw power bars or a charging indicator on an image of a battery, determined by battery charge voltage or percentage.
static void drawBattery(OLEDDisplay *display, int16_t x, int16_t y, uint8_t *imgBuffer, const PowerStatus *powerStatus)
{
@@ -470,14 +457,14 @@ static void drawBattery(OLEDDisplay *display, int16_t x, int16_t y, uint8_t *img
static void drawNodes(OLEDDisplay *display, int16_t x, int16_t y, NodeStatus *nodeStatus)
{
char usersString[20];
sprintf(usersString, "%d/%d", nodeStatus->getNumOnline(), nodeStatus->getNumTotal());
snprintf(usersString, sizeof(usersString), "%d/%d", nodeStatus->getNumOnline(), nodeStatus->getNumTotal());
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS)
display->drawFastImage(x, y + 3, 8, 8, imgUser);
#else
display->drawFastImage(x, y, 8, 8, imgUser);
#endif
display->drawString(x + 10, y - 2, usersString);
if(config.display.heading_bold)
if (config.display.heading_bold)
display->drawString(x + 11, y - 2, usersString);
}
@@ -487,20 +474,20 @@ static void drawGPS(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus
if (config.position.fixed_position) {
// GPS coordinates are currently fixed
display->drawString(x - 1, y - 2, "Fixed GPS");
if(config.display.heading_bold)
if (config.display.heading_bold)
display->drawString(x, y - 2, "Fixed GPS");
return;
}
if (!gps->getIsConnected()) {
display->drawString(x, y - 2, "No GPS");
if(config.display.heading_bold)
if (config.display.heading_bold)
display->drawString(x + 1, y - 2, "No GPS");
return;
}
display->drawFastImage(x, y, 6, 8, gps->getHasLock() ? imgPositionSolid : imgPositionEmpty);
if (!gps->getHasLock()) {
display->drawString(x + 8, y - 2, "No sats");
if(config.display.heading_bold)
if (config.display.heading_bold)
display->drawString(x + 9, y - 2, "No sats");
return;
} else {
@@ -521,28 +508,22 @@ static void drawGPS(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus
display->drawFastImage(x + 24, y, 8, 8, imgSatellite);
// Draw the number of satellites
sprintf(satsString, "%u", gps->getNumSatellites());
snprintf(satsString, sizeof(satsString), "%u", gps->getNumSatellites());
display->drawString(x + 34, y - 2, satsString);
if(config.display.heading_bold)
if (config.display.heading_bold)
display->drawString(x + 35, y - 2, satsString);
}
}
//Draw status when gps is disabled by PMU
// Draw status when gps is disabled by PMU
static void drawGPSpowerstat(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus *gps)
{
#ifdef HAS_PMU
String displayLine = "GPS disabled";
int16_t xPos = display->getStringWidth(displayLine);
if (!config.position.gps_enabled){
if (!config.position.gps_enabled) {
display->drawString(x + xPos, y, displayLine);
#ifdef GPS_POWER_TOGGLE
display->drawString(x + xPos, y - 2 + FONT_HEIGHT_SMALL, " by button");
#endif
//display->drawString(x + xPos, y + 2, displayLine);
}
#endif
}
static void drawGPSAltitude(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus *gps)
@@ -557,7 +538,7 @@ static void drawGPSAltitude(OLEDDisplay *display, int16_t x, int16_t y, const GP
} else {
geoCoord.updateCoords(int32_t(gps->getLatitude()), int32_t(gps->getLongitude()), int32_t(gps->getAltitude()));
displayLine = "Altitude: " + String(geoCoord.getAltitude()) + "m";
if (config.display.units == Config_DisplayConfig_DisplayUnits_IMPERIAL)
if (config.display.units == meshtastic_Config_DisplayConfig_DisplayUnits_IMPERIAL)
displayLine = "Altitude: " + String(geoCoord.getAltitude() * METERS_TO_FEET) + "ft";
display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(displayLine))) / 2, y, displayLine);
}
@@ -579,25 +560,26 @@ static void drawGPScoordinates(OLEDDisplay *display, int16_t x, int16_t y, const
geoCoord.updateCoords(int32_t(gps->getLatitude()), int32_t(gps->getLongitude()), int32_t(gps->getAltitude()));
if (gpsFormat != Config_DisplayConfig_GpsCoordinateFormat_DMS) {
if (gpsFormat != meshtastic_Config_DisplayConfig_GpsCoordinateFormat_DMS) {
char coordinateLine[22];
if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_DEC) { // Decimal Degrees
sprintf(coordinateLine, "%f %f", geoCoord.getLatitude() * 1e-7, geoCoord.getLongitude() * 1e-7);
} else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_UTM) { // Universal Transverse Mercator
sprintf(coordinateLine, "%2i%1c %06u %07u", geoCoord.getUTMZone(), geoCoord.getUTMBand(),
geoCoord.getUTMEasting(), geoCoord.getUTMNorthing());
} else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_MGRS) { // Military Grid Reference System
sprintf(coordinateLine, "%2i%1c %1c%1c %05u %05u", geoCoord.getMGRSZone(), geoCoord.getMGRSBand(),
geoCoord.getMGRSEast100k(), geoCoord.getMGRSNorth100k(), geoCoord.getMGRSEasting(),
geoCoord.getMGRSNorthing());
} else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_OLC) { // Open Location Code
if (gpsFormat == meshtastic_Config_DisplayConfig_GpsCoordinateFormat_DEC) { // Decimal Degrees
snprintf(coordinateLine, sizeof(coordinateLine), "%f %f", geoCoord.getLatitude() * 1e-7,
geoCoord.getLongitude() * 1e-7);
} else if (gpsFormat == meshtastic_Config_DisplayConfig_GpsCoordinateFormat_UTM) { // Universal Transverse Mercator
snprintf(coordinateLine, sizeof(coordinateLine), "%2i%1c %06u %07u", geoCoord.getUTMZone(), geoCoord.getUTMBand(),
geoCoord.getUTMEasting(), geoCoord.getUTMNorthing());
} else if (gpsFormat == meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MGRS) { // Military Grid Reference System
snprintf(coordinateLine, sizeof(coordinateLine), "%2i%1c %1c%1c %05u %05u", geoCoord.getMGRSZone(),
geoCoord.getMGRSBand(), geoCoord.getMGRSEast100k(), geoCoord.getMGRSNorth100k(),
geoCoord.getMGRSEasting(), geoCoord.getMGRSNorthing());
} else if (gpsFormat == meshtastic_Config_DisplayConfig_GpsCoordinateFormat_OLC) { // Open Location Code
geoCoord.getOLCCode(coordinateLine);
} else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_OSGR) { // Ordnance Survey Grid Reference
} else if (gpsFormat == meshtastic_Config_DisplayConfig_GpsCoordinateFormat_OSGR) { // Ordnance Survey Grid Reference
if (geoCoord.getOSGRE100k() == 'I' || geoCoord.getOSGRN100k() == 'I') // OSGR is only valid around the UK region
sprintf(coordinateLine, "%s", "Out of Boundary");
snprintf(coordinateLine, sizeof(coordinateLine), "%s", "Out of Boundary");
else
sprintf(coordinateLine, "%1c%1c %05u %05u", geoCoord.getOSGRE100k(), geoCoord.getOSGRN100k(),
geoCoord.getOSGREasting(), geoCoord.getOSGRNorthing());
snprintf(coordinateLine, sizeof(coordinateLine), "%1c%1c %05u %05u", geoCoord.getOSGRE100k(),
geoCoord.getOSGRN100k(), geoCoord.getOSGREasting(), geoCoord.getOSGRNorthing());
}
// If fixed position, display text "Fixed GPS" alternating with the coordinates.
@@ -610,14 +592,13 @@ static void drawGPScoordinates(OLEDDisplay *display, int16_t x, int16_t y, const
} else {
display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(coordinateLine))) / 2, y, coordinateLine);
}
} else {
char latLine[22];
char lonLine[22];
sprintf(latLine, "%2i° %2i' %2u\" %1c", geoCoord.getDMSLatDeg(), geoCoord.getDMSLatMin(), geoCoord.getDMSLatSec(),
geoCoord.getDMSLatCP());
sprintf(lonLine, "%3i° %2i' %2u\" %1c", geoCoord.getDMSLonDeg(), geoCoord.getDMSLonMin(), geoCoord.getDMSLonSec(),
geoCoord.getDMSLonCP());
snprintf(latLine, sizeof(latLine), "%2i° %2i' %2u\" %1c", geoCoord.getDMSLatDeg(), geoCoord.getDMSLatMin(),
geoCoord.getDMSLatSec(), geoCoord.getDMSLatCP());
snprintf(lonLine, sizeof(lonLine), "%3i° %2i' %2u\" %1c", geoCoord.getDMSLonDeg(), geoCoord.getDMSLonMin(),
geoCoord.getDMSLonSec(), geoCoord.getDMSLonCP());
display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(latLine))) / 2, y - FONT_HEIGHT_SMALL * 1, latLine);
display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(lonLine))) / 2, y, lonLine);
}
@@ -653,8 +634,8 @@ class Point
void scale(float f)
{
//We use -f here to counter the flip that happens
//on the y axis when drawing and rotating on screen
// We use -f here to counter the flip that happens
// on the y axis when drawing and rotating on screen
x *= f;
y *= -f;
}
@@ -699,7 +680,7 @@ static float estimatedHeading(double lat, double lon)
/// Sometimes we will have Position objects that only have a time, so check for
/// valid lat/lon
static bool hasPosition(NodeInfo *n)
static bool hasPosition(meshtastic_NodeInfo *n)
{
return n->has_position && (n->position.latitude_i != 0 || n->position.longitude_i != 0);
}
@@ -709,11 +690,11 @@ static uint16_t getCompassDiam(OLEDDisplay *display)
uint16_t diam = 0;
uint16_t offset = 0;
if (config.display.displaymode != Config_DisplayConfig_DisplayMode_DEFAULT)
if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT)
offset = FONT_HEIGHT_SMALL;
// get the smaller of the 2 dimensions and subtract 20
if(display->getWidth() > (display->getHeight() - offset)) {
if (display->getWidth() > (display->getHeight() - offset)) {
diam = display->getHeight() - offset;
// if 2/3 of the other size would be smaller, use that
if (diam > (display->getWidth() * 2 / 3)) {
@@ -725,7 +706,7 @@ static uint16_t getCompassDiam(OLEDDisplay *display)
diam = (display->getHeight() - offset) * 2 / 3;
}
}
return diam - 20;
};
@@ -756,10 +737,10 @@ static void drawNodeHeading(OLEDDisplay *display, int16_t compassX, int16_t comp
// Draw north
static void drawCompassNorth(OLEDDisplay *display, int16_t compassX, int16_t compassY, float myHeading)
{
//If north is supposed to be at the top of the compass we want rotation to be +0
if(config.display.compass_north_top)
// If north is supposed to be at the top of the compass we want rotation to be +0
if (config.display.compass_north_top)
myHeading = -0;
Point N1(-0.04f, 0.65f), N2(0.04f, 0.65f);
Point N3(-0.04f, 0.55f), N4(0.04f, 0.55f);
Point *rosePoints[] = {&N1, &N2, &N3, &N4};
@@ -786,7 +767,7 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
prevFrame = state->currentFrame;
nodeIndex = (nodeIndex + 1) % nodeDB.getNumNodes();
NodeInfo *n = nodeDB.getNodeByIndex(nodeIndex);
meshtastic_NodeInfo *n = nodeDB.getNodeByIndex(nodeIndex);
if (n->num == nodeDB.getNodeNum()) {
// Don't show our node, just skip to next
nodeIndex = (nodeIndex + 1) % nodeDB.getNumNodes();
@@ -795,14 +776,14 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
displayedNodeNum = n->num;
}
NodeInfo *node = nodeDB.getNodeByIndex(nodeIndex);
meshtastic_NodeInfo *node = nodeDB.getNodeByIndex(nodeIndex);
display->setFont(FONT_SMALL);
// The coordinates define the left starting point of the text
display->setTextAlignment(TEXT_ALIGN_LEFT);
if (config.display.displaymode == Config_DisplayConfig_DisplayMode_INVERTED) {
if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) {
display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL);
}
@@ -818,9 +799,6 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
else if (agoSecs < 120 * 60) // last 2 hrs
snprintf(lastStr, sizeof(lastStr), "%u minutes ago", agoSecs / 60);
else {
uint32_t hours_in_month = 730;
// Only show hours ago if it's been less than 6 months. Otherwise, we may have bad
// data.
if ((agoSecs / 60 / 60) < (hours_in_month * 6)) {
@@ -831,13 +809,13 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
}
static char distStr[20];
strcpy(distStr, "? km"); // might not have location data
NodeInfo *ourNode = nodeDB.getNode(nodeDB.getNodeNum());
strncpy(distStr, "? km", sizeof(distStr)); // might not have location data
meshtastic_NodeInfo *ourNode = nodeDB.getNode(nodeDB.getNodeNum());
const char *fields[] = {username, distStr, signalStr, lastStr, NULL};
int16_t compassX = 0, compassY = 0;
// coordinates for the center of the compass/circle
if (config.display.displaymode == Config_DisplayConfig_DisplayMode_DEFAULT) {
if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT) {
compassX = x + SCREEN_WIDTH - getCompassDiam(display) / 2 - 5;
compassY = y + SCREEN_HEIGHT / 2;
} else {
@@ -847,18 +825,18 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
bool hasNodeHeading = false;
if (ourNode && hasPosition(ourNode)) {
Position &op = ourNode->position;
meshtastic_Position &op = ourNode->position;
float myHeading = estimatedHeading(DegD(op.latitude_i), DegD(op.longitude_i));
drawCompassNorth(display, compassX, compassY, myHeading);
if (hasPosition(node)) {
// display direction toward node
hasNodeHeading = true;
Position &p = node->position;
meshtastic_Position &p = node->position;
float d =
GeoCoord::latLongToMeter(DegD(p.latitude_i), DegD(p.longitude_i), DegD(op.latitude_i), DegD(op.longitude_i));
if (config.display.units == Config_DisplayConfig_DisplayUnits_IMPERIAL) {
if (config.display.units == meshtastic_Config_DisplayConfig_DisplayUnits_IMPERIAL) {
if (d < (2 * MILES_TO_FEET))
snprintf(distStr, sizeof(distStr), "%.0f ft", d * METERS_TO_FEET);
else
@@ -874,7 +852,7 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
GeoCoord::bearing(DegD(op.latitude_i), DegD(op.longitude_i), DegD(p.latitude_i), DegD(p.longitude_i));
// If the top of the compass is a static north then bearingToOther can be drawn on the compass directly
// If the top of the compass is not a static north we need adjust bearingToOther based on heading
if(!config.display.compass_north_top)
if (!config.display.compass_north_top)
bearingToOther -= myHeading;
drawNodeHeading(display, compassX, compassY, bearingToOther);
}
@@ -887,7 +865,7 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
}
display->drawCircle(compassX, compassY, getCompassDiam(display) / 2);
if (config.display.displaymode == Config_DisplayConfig_DisplayMode_INVERTED) {
if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) {
display->setColor(BLACK);
}
// Must be after distStr is populated
@@ -908,7 +886,11 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
// }
// }
// #else
Screen::Screen(uint8_t address, int sda, int scl) : OSThread("Screen"), cmdQueue(32), dispdev(address, sda, scl), ui(&dispdev)
Screen::Screen(uint8_t address, int sda, int scl)
: OSThread("Screen"), cmdQueue(32),
dispdev(address, sda, scl,
screen_model == meshtastic_Config_DisplayConfig_OledType_OLED_SH1107 ? GEOMETRY_128_128 : GEOMETRY_128_64),
ui(&dispdev)
{
address_found = address;
cmdQueue.setReader(this);
@@ -958,6 +940,8 @@ void Screen::setup()
useDisplay = true;
#ifdef AutoOLEDWire_h
if (screen_model == meshtastic_Config_DisplayConfig_OledType_OLED_SH1107)
screen_model = meshtastic_Config_DisplayConfig_OledType_OLED_SH1106;
dispdev.setDetected(screen_model);
#endif
@@ -1000,8 +984,8 @@ void Screen::setup()
#ifdef SCREEN_MIRROR
dispdev.mirrorScreen();
#else
// Standard behaviour is to FLIP the screen (needed on T-Beam). If this config item is set, unflip it, and thereby logically flip it.
// If you have a headache now, you're welcome.
// Standard behaviour is to FLIP the screen (needed on T-Beam). If this config item is set, unflip it, and thereby logically
// flip it. If you have a headache now, you're welcome.
if (!config.display.flip_screen) {
dispdev.flipScreenVertically();
}
@@ -1010,7 +994,7 @@ void Screen::setup()
// Get our hardware ID
uint8_t dmac[6];
getMacAddr(dmac);
sprintf(ourId, "%02x%02x", dmac[4], dmac[5]);
snprintf(ourId, sizeof(ourId), "%02x%02x", dmac[4], dmac[5]);
// Turn on the display.
handleSetOn(true);
@@ -1071,7 +1055,7 @@ int32_t Screen::runOnce()
static const int bootOEMFrameCount = sizeof(bootOEMFrames) / sizeof(bootOEMFrames[0]);
ui.setFrames(bootOEMFrames, bootOEMFrameCount);
ui.update();
#ifndef USE_EINK
#ifndef USE_EINK
ui.update();
#endif
showingOEMBootScreen = false;
@@ -1079,7 +1063,7 @@ int32_t Screen::runOnce()
}
#ifndef DISABLE_WELCOME_UNSET
if (showingNormalScreen && config.lora.region == Config_LoRaConfig_RegionCode_UNSET) {
if (showingNormalScreen && config.lora.region == meshtastic_Config_LoRaConfig_RegionCode_UNSET) {
setWelcomeFrames();
}
#endif
@@ -1354,6 +1338,23 @@ void Screen::blink()
dispdev.setBrightness(brightness);
}
std::string Screen::drawTimeDelta(uint32_t days, uint32_t hours, uint32_t minutes, uint32_t seconds)
{
std::string uptime;
if (days > (hours_in_month * 6))
uptime = "?";
else if (days >= 2)
uptime = std::to_string(days) + "d";
else if (hours >= 2)
uptime = std::to_string(hours) + "h";
else if (minutes >= 1)
uptime = std::to_string(minutes) + "m";
else
uptime = std::to_string(seconds) + "s";
return uptime;
}
void Screen::handlePrint(const char *text)
{
// the string passed into us probably has a newline, but that would confuse the logging system
@@ -1399,7 +1400,7 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
// The coordinates define the left starting point of the text
display->setTextAlignment(TEXT_ALIGN_LEFT);
if (config.display.displaymode == Config_DisplayConfig_DisplayMode_INVERTED) {
if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) {
display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL);
display->setColor(BLACK);
}
@@ -1413,33 +1414,29 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
// Display power status
if (powerStatus->getHasBattery()) {
if (config.display.displaymode == Config_DisplayConfig_DisplayMode_DEFAULT) {
drawBattery(display, x , y + 2, imgBattery, powerStatus);
if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT) {
drawBattery(display, x, y + 2, imgBattery, powerStatus);
} else {
drawBattery(display, x + 1, y + 3, imgBattery, powerStatus);
}
} else if (powerStatus->knowsUSB()) {
if (config.display.displaymode == Config_DisplayConfig_DisplayMode_DEFAULT) {
if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT) {
display->drawFastImage(x, y + 2, 16, 8, powerStatus->getHasUSB() ? imgUSB : imgPower);
} else {
display->drawFastImage(x + 1, y + 3, 16, 8, powerStatus->getHasUSB() ? imgUSB : imgPower);
}
}
// Display nodes status
if (config.display.displaymode == Config_DisplayConfig_DisplayMode_DEFAULT) {
if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT) {
drawNodes(display, x + (SCREEN_WIDTH * 0.25), y + 2, nodeStatus);
} else {
drawNodes(display, x + (SCREEN_WIDTH * 0.25), y + 3, nodeStatus);
}
// Display GPS status
if (!config.position.gps_enabled){
int16_t yPos = y + 2;
#ifdef GPS_POWER_TOGGLE
yPos = (y + 10 + FONT_HEIGHT_SMALL);
#endif
drawGPSpowerstat(display, x, yPos, gpsStatus);
if (!config.position.gps_enabled) {
drawGPSpowerstat(display, x, y + 2, gpsStatus);
} else {
if (config.display.displaymode == Config_DisplayConfig_DisplayMode_DEFAULT) {
if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT) {
drawGPS(display, x + (SCREEN_WIDTH * 0.63), y + 2, gpsStatus);
} else {
drawGPS(display, x + (SCREEN_WIDTH * 0.63), y + 3, gpsStatus);
@@ -1451,27 +1448,36 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
display->drawString(x, y + FONT_HEIGHT_SMALL, channelStr);
// Draw our hardware ID to assist with bluetooth pairing. Either prefix with Info or S&F Logo
if (moduleConfig.store_forward.enabled) {
#ifdef ARCH_ESP32
if (millis() - storeForwardModule->lastHeartbeat > (storeForwardModule->heartbeatInterval * 1200)) { //no heartbeat, overlap a bit
#ifdef ARCH_ESP32
if (millis() - storeForwardModule->lastHeartbeat >
(storeForwardModule->heartbeatInterval * 1200)) { // no heartbeat, overlap a bit
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS)
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 12, 8, imgQuestionL1);
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 11 + FONT_HEIGHT_SMALL, 12, 8, imgQuestionL2);
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 12, 8,
imgQuestionL1);
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 11 + FONT_HEIGHT_SMALL, 12, 8,
imgQuestionL2);
#else
display->drawFastImage(x + SCREEN_WIDTH - 10 - display->getStringWidth(ourId), y + 2 + FONT_HEIGHT_SMALL, 8, 8, imgQuestion);
display->drawFastImage(x + SCREEN_WIDTH - 10 - display->getStringWidth(ourId), y + 2 + FONT_HEIGHT_SMALL, 8, 8,
imgQuestion);
#endif
} else {
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS)
display->drawFastImage(x + SCREEN_WIDTH - 18 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 16, 8, imgSFL1);
display->drawFastImage(x + SCREEN_WIDTH - 18 - display->getStringWidth(ourId), y + 11 + FONT_HEIGHT_SMALL, 16, 8, imgSFL2);
display->drawFastImage(x + SCREEN_WIDTH - 18 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 16, 8,
imgSFL1);
display->drawFastImage(x + SCREEN_WIDTH - 18 - display->getStringWidth(ourId), y + 11 + FONT_HEIGHT_SMALL, 16, 8,
imgSFL2);
#else
display->drawFastImage(x + SCREEN_WIDTH - 13 - display->getStringWidth(ourId), y + 2 + FONT_HEIGHT_SMALL, 11, 8, imgSF);
display->drawFastImage(x + SCREEN_WIDTH - 13 - display->getStringWidth(ourId), y + 2 + FONT_HEIGHT_SMALL, 11, 8,
imgSF);
#endif
}
#endif
#endif
} else {
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS)
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 12, 8, imgInfoL1);
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 11 + FONT_HEIGHT_SMALL, 12, 8, imgInfoL2);
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 12, 8,
imgInfoL1);
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 11 + FONT_HEIGHT_SMALL, 12, 8,
imgInfoL2);
#else
display->drawFastImage(x + SCREEN_WIDTH - 10 - display->getStringWidth(ourId), y + 2 + FONT_HEIGHT_SMALL, 8, 8, imgInfo);
#endif
@@ -1503,23 +1509,23 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i
// The coordinates define the left starting point of the text
display->setTextAlignment(TEXT_ALIGN_LEFT);
if (config.display.displaymode == Config_DisplayConfig_DisplayMode_INVERTED) {
if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) {
display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL);
display->setColor(BLACK);
}
if (WiFi.status() != WL_CONNECTED) {
display->drawString(x, y, String("WiFi: Not Connected"));
if(config.display.heading_bold)
if (config.display.heading_bold)
display->drawString(x + 1, y, String("WiFi: Not Connected"));
} else {
display->drawString(x, y, String("WiFi: Connected"));
if(config.display.heading_bold)
if (config.display.heading_bold)
display->drawString(x + 1, y, String("WiFi: Connected"));
display->drawString(x + SCREEN_WIDTH - display->getStringWidth("RSSI " + String(WiFi.RSSI())), y,
"RSSI " + String(WiFi.RSSI()));
if(config.display.heading_bold) {
if (config.display.heading_bold) {
display->drawString(x + SCREEN_WIDTH - display->getStringWidth("RSSI " + String(WiFi.RSSI())) - 1, y,
"RSSI " + String(WiFi.RSSI()));
}
@@ -1635,7 +1641,7 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
// The coordinates define the left starting point of the text
display->setTextAlignment(TEXT_ALIGN_LEFT);
if (config.display.displaymode == Config_DisplayConfig_DisplayMode_INVERTED) {
if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) {
display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL);
display->setColor(BLACK);
}
@@ -1650,37 +1656,40 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
// Line 1
display->drawString(x, y, batStr);
if(config.display.heading_bold)
if (config.display.heading_bold)
display->drawString(x + 1, y, batStr);
} else {
// Line 1
display->drawString(x, y, String("USB"));
if(config.display.heading_bold)
if (config.display.heading_bold)
display->drawString(x + 1, y, String("USB"));
}
auto mode = "";
switch (config.lora.modem_preset) {
case Config_LoRaConfig_ModemPreset_SHORT_SLOW:
case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_SLOW:
mode = "ShortS";
break;
case Config_LoRaConfig_ModemPreset_SHORT_FAST:
case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST:
mode = "ShortF";
break;
case Config_LoRaConfig_ModemPreset_MEDIUM_SLOW:
case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_SLOW:
mode = "MedS";
break;
case Config_LoRaConfig_ModemPreset_MEDIUM_FAST:
case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_FAST:
mode = "MedF";
break;
case Config_LoRaConfig_ModemPreset_LONG_SLOW:
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_SLOW:
mode = "LongS";
break;
case Config_LoRaConfig_ModemPreset_LONG_FAST:
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST:
mode = "LongF";
break;
case Config_LoRaConfig_ModemPreset_VERY_LONG_SLOW:
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE:
mode = "LongM";
break;
case meshtastic_Config_LoRaConfig_ModemPreset_VERY_LONG_SLOW:
mode = "VeryL";
break;
default:
@@ -1689,7 +1698,7 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
}
display->drawString(x + SCREEN_WIDTH - display->getStringWidth(mode), y, mode);
if(config.display.heading_bold)
if (config.display.heading_bold)
display->drawString(x + SCREEN_WIDTH - display->getStringWidth(mode) - 1, y, mode);
// Line 2
@@ -1706,15 +1715,7 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
display->setColor(WHITE);
// Show uptime as days, hours, minutes OR seconds
String uptime;
if (days >= 2)
uptime += String(days) + "d ";
else if (hours >= 2)
uptime += String(hours) + "h ";
else if (minutes >= 1)
uptime += String(minutes) + "m ";
else
uptime += String(seconds) + "s ";
std::string uptime = screen->drawTimeDelta(days, hours, minutes, seconds);
uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityDevice);
if (rtc_sec > 0) {
@@ -1729,28 +1730,31 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
int min = (hms % SEC_PER_HOUR) / SEC_PER_MIN;
int sec = (hms % SEC_PER_HOUR) % SEC_PER_MIN; // or hms % SEC_PER_MIN
char timebuf[9];
snprintf(timebuf, sizeof(timebuf), "%02d:%02d:%02d", hour, min, sec);
char timebuf[10];
snprintf(timebuf, sizeof(timebuf), " %02d:%02d:%02d", hour, min, sec);
uptime += timebuf;
}
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, uptime);
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, uptime.c_str());
// Display Channel Utilization
char chUtil[13];
sprintf(chUtil, "ChUtil %2.0f%%", airTime->channelUtilizationPercent());
snprintf(chUtil, sizeof(chUtil), "ChUtil %2.0f%%", airTime->channelUtilizationPercent());
display->drawString(x + SCREEN_WIDTH - display->getStringWidth(chUtil), y + FONT_HEIGHT_SMALL * 1, chUtil);
if (config.position.gps_enabled) {
// Line 3
if (config.display.gps_format !=
Config_DisplayConfig_GpsCoordinateFormat_DMS) // if DMS then don't draw altitude
drawGPSAltitude(display, x, y + FONT_HEIGHT_SMALL * 2, gpsStatus);
if (config.position.gps_enabled) {
// Line 3
if (config.display.gps_format !=
meshtastic_Config_DisplayConfig_GpsCoordinateFormat_DMS) // if DMS then don't draw altitude
drawGPSAltitude(display, x, y + FONT_HEIGHT_SMALL * 2, gpsStatus);
// Line 4
drawGPScoordinates(display, x, y + FONT_HEIGHT_SMALL * 3, gpsStatus);
} else {
drawGPSpowerstat(display, x - (SCREEN_WIDTH / 4), y + FONT_HEIGHT_SMALL * 2, gpsStatus);
}
// Line 4
drawGPScoordinates(display, x, y + FONT_HEIGHT_SMALL * 3, gpsStatus);
} else {
drawGPSpowerstat(display, x - (SCREEN_WIDTH / 4), y + FONT_HEIGHT_SMALL * 2, gpsStatus);
#ifdef GPS_POWER_TOGGLE
display->drawString(x + 30, (y + FONT_HEIGHT_SMALL * 3), " by button");
#endif
}
/* Display a heartbeat pixel that blinks every time the frame is redrawn */
#ifdef SHOW_REDRAWS
if (heartbeat)
@@ -1791,7 +1795,7 @@ int Screen::handleStatusUpdate(const meshtastic::Status *arg)
return 0;
}
int Screen::handleTextMessage(const MeshPacket *packet)
int Screen::handleTextMessage(const meshtastic_MeshPacket *packet)
{
if (showingNormalScreen) {
setFrames(); // Regen the list of screens (will show new text message)

View File

@@ -7,15 +7,15 @@
namespace graphics
{
// Noop class for boards without screen.
class Screen
class Screen
{
public:
explicit Screen(char){}
explicit Screen(char) {}
void onPress() {}
void setup() {}
void setOn(bool) {}
void print(const char*){}
void adjustBrightness(){}
void print(const char *) {}
void adjustBrightness() {}
void doDeepSleep() {}
void forceDisplay() {}
void startBluetoothPinScreen(uint32_t pin) {}
@@ -23,7 +23,7 @@ class Screen
void startRebootScreen() {}
void startFirmwareUpdateScreen() {}
};
}
} // namespace graphics
#else
#include <cstring>
@@ -34,7 +34,7 @@ class Screen
#ifdef USE_ST7567
#include <ST7567Wire.h>
#elif defined(USE_SH1106)
#elif defined(USE_SH1106) || defined(USE_SH1107)
#include <SH1106Wire.h>
#elif defined(USE_SSD1306)
#include <SSD1306Wire.h>
@@ -49,9 +49,9 @@ class Screen
#include "commands.h"
#include "concurrency/LockGuard.h"
#include "concurrency/OSThread.h"
#include "mesh/MeshModule.h"
#include "power.h"
#include <string>
#include "mesh/MeshModule.h"
// 0 to 255, though particular variants might define different defaults
#ifndef BRIGHTNESS_DEFAULT
@@ -110,8 +110,8 @@ class Screen : public concurrency::OSThread
CallbackObserver<Screen, const meshtastic::Status *>(this, &Screen::handleStatusUpdate);
CallbackObserver<Screen, const meshtastic::Status *> nodeStatusObserver =
CallbackObserver<Screen, const meshtastic::Status *>(this, &Screen::handleStatusUpdate);
CallbackObserver<Screen, const MeshPacket *> textMessageObserver =
CallbackObserver<Screen, const MeshPacket *>(this, &Screen::handleTextMessage);
CallbackObserver<Screen, const meshtastic_MeshPacket *> textMessageObserver =
CallbackObserver<Screen, const meshtastic_MeshPacket *>(this, &Screen::handleTextMessage);
CallbackObserver<Screen, const UIFrameEvent *> uiFrameEventObserver =
CallbackObserver<Screen, const UIFrameEvent *>(this, &Screen::handleUIFrameEvent);
@@ -132,13 +132,14 @@ class Screen : public concurrency::OSThread
void setOn(bool on)
{
if (!on)
handleSetOn(false); // We handle off commands immediately, because they might be called because the CPU is shutting down
handleSetOn(
false); // We handle off commands immediately, because they might be called because the CPU is shutting down
else
enqueueCmd(ScreenCmd{.cmd = on ? Cmd::SET_ON : Cmd::SET_OFF});
}
/**
* Prepare the display for the unit going to the lowest power mode possible. Most screens will just
* Prepare the display for the unit going to the lowest power mode possible. Most screens will just
* poweroff, but eink screens will show a "I'm sleeping" graphic, possibly with a QR code
*/
void doDeepSleep();
@@ -205,6 +206,9 @@ class Screen : public concurrency::OSThread
}
}
/// generates a very brief time delta display
std::string drawTimeDelta(uint32_t days, uint32_t hours, uint32_t minutes, uint32_t seconds);
/// Overrides the default utf8 character conversion, to replace empty space with question marks
static char customFontTableLookup(const uint8_t ch)
{
@@ -223,29 +227,53 @@ class Screen : public concurrency::OSThread
LASTCHAR = ch;
switch (last) { // conversion depending on first UTF8-character
case 0xC2: {
SKIPREST = false;
return (uint8_t)ch;
}
case 0xC3: {
SKIPREST = false;
return (uint8_t)(ch | 0xC0);
}
// map UTF-8 cyrillic chars to it Windows-1251 (CP-1251) ASCII codes
// note: in this case we must use compatible font - provided ArialMT_Plain_10/16/24 by 'ThingPulse/esp8266-oled-ssd1306' library
// have empty chars for non-latin ASCII symbols
case 0xD0: {
SKIPREST = false;
if (ch == 129) return (uint8_t)(168); // Ё
if (ch > 143 && ch < 192) return (uint8_t)(ch + 48);
break;
}
case 0xD1: {
SKIPREST = false;
if (ch == 145) return (uint8_t)(184); // ё
if (ch > 127 && ch < 144) return (uint8_t)(ch + 112);
break;
}
case 0xC2: {
SKIPREST = false;
return (uint8_t)ch;
}
case 0xC3: {
SKIPREST = false;
return (uint8_t)(ch | 0xC0);
}
// map UTF-8 cyrillic chars to it Windows-1251 (CP-1251) ASCII codes
// note: in this case we must use compatible font - provided ArialMT_Plain_10/16/24 by 'ThingPulse/esp8266-oled-ssd1306'
// library have empty chars for non-latin ASCII symbols
case 0xD0: {
SKIPREST = false;
if (ch == 132)
return (uint8_t)(170); // Є
if (ch == 134)
return (uint8_t)(178); // І
if (ch == 135)
return (uint8_t)(175); // Ї
if (ch == 129)
return (uint8_t)(168); // Ё
if (ch > 143 && ch < 192)
return (uint8_t)(ch + 48);
break;
}
case 0xD1: {
SKIPREST = false;
if (ch == 148)
return (uint8_t)(186); // є
if (ch == 150)
return (uint8_t)(179); // і
if (ch == 151)
return (uint8_t)(191); // ї
if (ch == 145)
return (uint8_t)(184); // ё
if (ch > 127 && ch < 144)
return (uint8_t)(ch + 112);
break;
}
case 0xD2: {
SKIPREST = false;
if (ch == 144)
return (uint8_t)(165); // Ґ
if (ch == 145)
return (uint8_t)(180); // ґ
break;
}
}
// We want to strip out prefix chars for two-byte char formats
@@ -268,7 +296,7 @@ class Screen : public concurrency::OSThread
DebugInfo *debug_info() { return &debugInfo; }
int handleStatusUpdate(const meshtastic::Status *arg);
int handleTextMessage(const MeshPacket *arg);
int handleTextMessage(const meshtastic_MeshPacket *arg);
int handleUIFrameEvent(const UIFrameEvent *arg);
/// Used to force (super slow) eink displays to draw critical frames
@@ -342,10 +370,7 @@ class Screen : public concurrency::OSThread
/// Display device
// #ifdef RAK4630
// EInkDisplay dispdev;
// AutoOLEDWire dispdev_oled;
#ifdef USE_SH1106
#if defined(USE_SH1106) || defined(USE_SH1107)
SH1106Wire dispdev;
#elif defined(USE_SSD1306)
SSD1306Wire dispdev;

View File

@@ -8,7 +8,7 @@
static TFT_eSPI tft = TFT_eSPI(); // Invoke library, pins defined in User_Setup.h
TFTDisplay::TFTDisplay(uint8_t address, int sda, int scl)
TFTDisplay::TFTDisplay(uint8_t address, int sda, int scl, uint8_t screen_model)
{
#ifdef SCREEN_ROTATE
setGeometry(GEOMETRY_RAWMODE, TFT_HEIGHT, TFT_WIDTH);
@@ -22,7 +22,7 @@ void TFTDisplay::display(void)
{
concurrency::LockGuard g(spiLock);
uint16_t x,y;
uint16_t x, y;
for (y = 0; y < displayHeight; y++) {
for (x = 0; x < displayWidth; x++) {

Some files were not shown because too many files have changed in this diff Show More