Compare commits

..

167 Commits

Author SHA1 Message Date
Thomas Göttgens
5ec624d9c3 Merge pull request #2462 from meshtastic/bug-2451
probably fixes #2451 - please test
2023-05-06 23:37:35 +02:00
Thomas Göttgens
b4ff37104a fix NMEA Timestamp for good 2023-05-06 23:16:39 +02:00
Thomas Göttgens
81bfd69a41 fmt 2023-05-06 18:13:52 +02:00
Thomas Göttgens
57aaf7f6ee Merge branch 'bug-2451' of github.com:meshtastic/firmware into bug-2451 2023-05-06 18:11:56 +02:00
Thomas Göttgens
9b6ac98ae0 use the device time, only use gps timestamp as a fallback. 2023-05-06 18:10:20 +02:00
Thomas Göttgens
e1c4968c58 wrong datapoint 2023-05-06 18:10:20 +02:00
Thomas Göttgens
694fd04367 probably fixes #2451 - please test 2023-05-06 18:10:20 +02:00
Thomas Göttgens
cdc8bf44e9 use the device time, only use gps timestamp as a fallback. 2023-05-06 18:10:00 +02:00
Ben Meadors
09d48f659e RAK14001 RGB LED support (#2464)
* WIP

* WIP

* Moved it

* More random strobey behavior

* Guard to RAK4630 devices for now

* Oops

* Ship it
2023-05-06 07:17:40 -05:00
Thomas Göttgens
39aa756100 wrong datapoint 2023-05-05 14:29:14 +02:00
Thomas Göttgens
17e25babb1 probably fixes #2451 - please test 2023-05-05 14:29:14 +02:00
Manuel Verch
7c9d0a022a fix AI C3 DevKit-M configuration 2023-05-05 09:39:22 +02:00
Thomas Göttgens
313860c8a4 fix #2460 - we only really need the router object after nodedb init, so lets move it there. 2023-05-04 11:06:49 +02:00
IhorNehrutsa
e360c62480 RemoteHardwareModule.cpp: Hot Fix digitalReads() pinModes(mask, INPUT_PULLUP) (#2459) 2023-05-03 21:09:18 -05:00
IhorNehrutsa
973b30fc0b Update RemoteHardwareModule.cpp (#2454) 2023-05-03 06:25:03 -05:00
Ben Meadors
a6385a522d Disable TX/RX EN in favor of power EN over TX_EN (#2456)
* Disable TX/RX EN in favor of power EN over TX_EN

* Oops
2023-05-03 06:24:09 -05:00
github-actions[bot]
b6ff80f0b7 [create-pull-request] automated change (#2453)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-05-01 17:36:38 -05:00
Ben Meadors
7ef12c77a8 Add initial screen for receiving waypoints (#2452) 2023-05-01 16:10:27 -05:00
Mark Trevor Birss
a27d354364 Add board - BPI PicoW ESP32-S3 SX1262 (#2450)
* Add files via upload

* Add files via upload
2023-05-01 07:12:00 -05:00
Manuel Verch
6e26f95df9 Make trunk happy again 2023-04-22 09:08:55 +02:00
Manuel Verch
5dfb5172c2 try-fix: router goes sporadically into DS 2023-04-22 09:08:55 +02:00
Thomas Göttgens
e0bb95ca94 implement dynamic userbutton overwrite. fix #2434 2023-04-21 16:50:22 +02:00
Thomas Göttgens
1621fbb5ab add debug/info print 2023-04-21 16:03:48 +02:00
Thomas Göttgens
ac40f77694 Draft for now, please test 2023-04-21 16:03:48 +02:00
Thomas Göttgens
9700fa55a3 Merge pull request #2438 from meshtastic/mqtt-debug-fix
fix topic construction for mqtt debug
2023-04-18 14:30:59 +02:00
Thomas Göttgens
87c59d7d61 fmt 2023-04-18 14:08:06 +02:00
Thomas Göttgens
584615bb4b fix topic construction for mqtt debug 2023-04-18 13:37:50 +02:00
github-actions[bot]
c452c2ab40 [create-pull-request] automated change (#2437)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-04-17 19:42:54 -05:00
github-actions[bot]
d43ddc9ec2 [create-pull-request] automated change (#2436) 2023-04-17 15:42:42 -05:00
Thomas Göttgens
a76cb94851 Revert "Trying to debug transient "disconnects" in iOS (#2312)" (#2435)
This reverts commit d17aafa91a.
2023-04-17 11:22:12 -05:00
Thomas Göttgens
da75ae21ff Merge pull request #2298 from meshtastic/2264-feature-check-for-low-heap-before-adding-to-nodedb-was-reboot-loop-heap-too-low
2264 Check for memory before extending the nodedb
2023-04-15 09:13:55 +02:00
Thomas Göttgens
a30c07e6b4 Merge branch 'master' into 2264-feature-check-for-low-heap-before-adding-to-nodedb-was-reboot-loop-heap-too-low 2023-04-14 19:56:01 +02:00
Thomas Göttgens
309d4fc7f2 add flush to filesystem before closing write file. 2023-04-14 13:25:06 +02:00
Thomas Göttgens
a13775bd70 Merge branch 'master' into 2264-feature-check-for-low-heap-before-adding-to-nodedb-was-reboot-loop-heap-too-low 2023-04-13 23:50:21 +02:00
Thomas Göttgens
b43a5bc4f8 Fix missing msh default topic. 2023-04-13 23:17:05 +02:00
Thomas Göttgens
ec44ca49fd Merge branch 'master' into 2264-feature-check-for-low-heap-before-adding-to-nodedb-was-reboot-loop-heap-too-low 2023-04-13 23:09:33 +02:00
Thomas Göttgens
5d41e9fe9d don't grow nodedb if memory is tight.
also remove unconditional reboot on low heap. This is counter productive with this change
2023-04-13 23:09:02 +02:00
Thomas Göttgens
7bd836673e return shutdown time to 5 seconds. 2023-04-13 19:53:56 +02:00
Thomas Göttgens
e0da661632 remove screen brightness again 2023-04-13 15:32:29 +02:00
Thomas Göttgens
a9ce4338ff update library version 2023-04-12 19:04:19 +02:00
Thomas Göttgens
a284439d7e Merge branch 'master' into 2264-feature-check-for-low-heap-before-adding-to-nodedb-was-reboot-loop-heap-too-low 2023-04-12 16:27:36 +02:00
Thomas Göttgens
10fac072bb move codec2 repo to org 2023-04-12 14:39:25 +02:00
Thomas Göttgens
d60ccb42da pretty print 2023-04-12 10:06:04 +02:00
thebentern
3598351689 [create-pull-request] automated change 2023-04-11 20:14:31 +02:00
Thomas Göttgens
74ed166ff0 Merge branch 'master' of github.com:meshtastic/firmware 2023-04-11 20:11:04 +02:00
Thomas Göttgens
0afeba0c86 generate dynamic device array for use in CI scripts
Usage: generate_ci_matrix.py platform [extra]
e.g. generate_ci_matrix.py esp32 or generate_ci_matrix.py esp32 extra
2023-04-11 20:10:54 +02:00
github-actions[bot]
ee971e376a [create-pull-request] automated change (#2424)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-04-11 08:01:49 -05:00
Thomas Göttgens
eeeb7c5080 i wasn't asking... 2023-04-11 14:37:08 +02:00
Thomas Göttgens
f526c4cc5a trxfix portduino 2023-04-11 14:37:08 +02:00
Thomas Göttgens
a9eb19fc62 fix parameters and compilation 2023-04-11 14:37:08 +02:00
Thomas Göttgens
29c13b5c30 resolve #2364
- fix wrong debug print
- change shutdown logic for t-beam if PMU is detected
- wait for 10 seconds instead of 5 for shutdown and resurrect screen brightness adjust for @karamo
2023-04-11 14:37:08 +02:00
Manuel Verch
f0c4c18a79 Fix for nodeInfo change to inform phone 2023-04-11 14:01:01 +02:00
Thomas Göttgens
320bf57687 tryfix #2416 - lock some guards. 2023-04-10 17:00:15 +02:00
Ben Meadors
4b89f7dfcb Merge branch 'master' into 2264-feature-check-for-low-heap-before-adding-to-nodedb-was-reboot-loop-heap-too-low 2023-04-07 07:55:26 -05:00
Thomas Göttgens
43cff7adc9 Implement #2380 (#2418) 2023-04-07 07:52:23 -05:00
github-actions[bot]
d4e42898b1 [create-pull-request] automated change (#2417)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-04-07 07:14:40 -05:00
Manuel Verch
82ab38d3e6 Revert changes on wakeup 2023-04-04 23:19:36 +02:00
github-actions[bot]
aa96ea02c6 [create-pull-request] automated change (#2411)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-04-04 14:13:26 -05:00
Ben Meadors
242f880764 Dear trunk, please don't be petty 2023-04-04 09:42:12 -05:00
Ben Meadors
de08360271 Protos tag for release 2023-04-04 08:15:59 -05:00
ghostop14
990d418dc8 Add MQTT TLS Support for WIFI-Enabled Devices (#2410)
* Testing TLS MQTT Support

* Working TLS connections

* Testing TLS MQTT Support

* Working TLS connections

* Added protobuf support for mqtt.tls_enabled

* fix 'em up good

* don't commit this stuff, jeeez

* there i fixed it

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
2023-04-04 08:14:47 -05:00
Ben Meadors
f8db02c622 Merge branch 'master' into 2264-feature-check-for-low-heap-before-adding-to-nodedb-was-reboot-loop-heap-too-low 2023-04-04 07:22:40 -05:00
Thomas Göttgens
fc8d16bb08 Merge pull request #2403 from mverch67/fix-2402
Fix for device display issues
2023-04-03 23:55:33 +02:00
Thomas Göttgens
af65013e49 Merge branch 'master' into fix-2402 2023-04-03 23:06:48 +02:00
Manuel
b1937e03ac fix: store NodeDB persistently (#2405)
* fix for 2404

* fix for 2404

* removed superfluous saveToDisk in reloadOwner()
2023-04-03 16:01:05 -05:00
Manuel Verch
23e6bc32c0 make cpptools happy 2023-04-03 20:14:57 +02:00
Manuel Verch
bd1e747fc9 Merge branch 'fix-2402' of https://github.com/mverch67/meshtastic-firmware into fix-2402 2023-04-03 19:46:52 +02:00
Manuel Verch
3c0817340a Fixed blank screen button issue and SX126x wakeup 2023-04-03 19:45:12 +02:00
Manuel Verch
9a42861766 make trunk happy 2023-04-03 18:06:36 +02:00
Manuel Verch
038ff0f6cb Fix for device display issues 2023-04-03 18:06:36 +02:00
github-actions[bot]
918b509be8 [create-pull-request] automated change (#2408)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-04-03 10:45:37 -05:00
Manuel Verch
9239698004 make trunk happy 2023-04-03 08:52:21 +02:00
Manuel Verch
71479a6b17 Fix for device display issues 2023-04-02 21:28:12 +02:00
Ben Meadors
b4bcae98cd Fixed invalid channel name text (#2400) 2023-04-02 08:33:38 -05:00
Thomas Göttgens
294771cb44 fix -705 error on SX128x and some SX126x 2023-04-02 15:04:50 +02:00
Thomas Göttgens
1398611276 trunk fmt 2023-04-02 11:35:25 +02:00
Vladislav Osmanov
fbc3b2beee missing EXT_PWR_DETECT pinMode definition 2023-04-02 11:35:25 +02:00
Vladislav Osmanov
6bf538e26f EXT_PWR_DETECT pin to detect external power source for boards without the power management chip 2023-04-02 11:35:25 +02:00
Thomas Göttgens
713b5fbe96 try to update trunk to latest version. 2023-03-31 12:51:26 +02:00
Thomas Göttgens
ed96321406 fix newline detection in error printing
Our code check for newline in the format string, not in the parameter
2023-03-31 11:04:15 +02:00
Thomas Göttgens
39d8ae64e7 Merge branch 'master' into 2264-feature-check-for-low-heap-before-adding-to-nodedb-was-reboot-loop-heap-too-low 2023-03-30 11:10:18 +02:00
Thomas Göttgens
3f07251d23 fmt 2023-03-30 10:46:39 +02:00
Mark Trevor Birss
657f22d058 Update EInkDisplay2.cpp 2023-03-30 10:46:39 +02:00
github-actions[bot]
bf1fbc6c0d [create-pull-request] automated change (#2395)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-03-29 19:19:19 -05:00
Ben Meadors
5679a82195 Support double tap as button press for supported accelerometers (#2393)
* For Garth

* Push it real good

* Wut

* Double tap

* Move disable logic

* Actually return

* Reinitialize setClick in thread body

* Initialize later so that we actually have nodedb on init

* Fixes
2023-03-29 13:04:02 -05:00
Thomas Göttgens
2edc35d34b Logic Late-Fix to the last PR 2023-03-29 15:14:48 +02:00
sbias
26d18244f0 Add nodedb channel handling (#2384)
* send ourNodeInfo to channel we got a message we heared someone new

* store node-channel into nodeDB

* use channel from nodeDb to send local messages

* update protobufs

* fmt and fix braces

* respect requested channel for local send, only store channel while getting a nodeinfo packet

---------

Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-03-29 06:51:22 -05:00
Thomas Göttgens
82ba59765c trunk it baby 2023-03-29 13:41:45 +02:00
Mark Trevor Birss
7930aa1635 Update platformio.ini 2023-03-29 13:41:45 +02:00
Mark Trevor Birss
c55751964e Update platformio.ini 2023-03-29 13:41:45 +02:00
Mark Trevor Birss
b9b1cce6a5 Update platformio.ini 2023-03-29 13:41:45 +02:00
Mark Trevor Birss
044ef75fef Update platformio.ini 2023-03-29 13:41:45 +02:00
Mark Trevor Birss
9f940139a0 Update platformio.ini 2023-03-29 13:41:45 +02:00
Mark Trevor Birss
fdb09d4fba Add files via upload 2023-03-29 13:41:45 +02:00
Mark Trevor Birss
1968f3c45b Delete EInkDisplay2.cpp 2023-03-29 13:41:45 +02:00
Mark Trevor Birss
790df42987 Add files via upload 2023-03-29 13:41:45 +02:00
Mark Trevor Birss
9a9279dd78 Add files via upload 2023-03-29 13:41:45 +02:00
thebentern
1e54a5d45c [create-pull-request] automated change 2023-03-28 12:57:23 +02:00
Ben Meadors
23272daffe Threshold based smart position broadcasts (#2388)
* Overhaul smart broadcast with new thresholds

* Fixed badly spelt protos

* That's not the right thing

* Format specifiers

* Fmt

* Units

* Default distance threshold of 100
2023-03-27 14:09:22 -05:00
Thomas Göttgens
6e685b0a54 Merge branch 'master' into 2264-feature-check-for-low-heap-before-adding-to-nodedb-was-reboot-loop-heap-too-low 2023-03-27 15:31:32 +02:00
Dan Fay
1af7e48136 Fixed the semi-silent failure to regenerate protobufs on Linux (#2383)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-03-27 06:52:48 -05:00
lewishe
eda00b7b9c Change to Variation Macro Definition 2023-03-27 11:27:57 +02:00
Thomas Göttgens
1898fe850e trunk format 2023-03-27 11:27:57 +02:00
lewishe
15dbe5da97 Added t-beam v1.2 support 2023-03-27 11:27:57 +02:00
GUVWAF
8f736c8ecc Remove sending network ping to displayed node on interval 2023-03-26 16:16:01 +02:00
Thomas Göttgens
8a81f190b8 Merge pull request #2386 from meshtastic/channel-num-fix
fix channel num in json output
2023-03-25 20:35:20 +01:00
Thomas Göttgens
1425657a3c fix channel num in json output 2023-03-25 20:14:04 +01:00
Thomas Göttgens
02041cb605 Merge pull request #2385 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2023-03-25 14:56:33 +01:00
caveman99
1f130d671b [create-pull-request] automated change 2023-03-25 13:38:35 +00:00
Thomas Göttgens
d62e56f428 Merge pull request #2381 from meshtastic/HPD17-PA
Add Power Restraint for 1280 PA Model
2023-03-25 14:24:02 +01:00
Thomas Göttgens
5ac24bb33b Update SX128xInterface.cpp 2023-03-25 14:23:30 +01:00
Thomas Göttgens
2c259b8464 Add Power Restraint for 1280 PA Model
Add Debug Print for all module parameters
Add RX/TX Switch to 1280
2023-03-24 16:57:30 +01:00
github-actions[bot]
9d6e1ce8e5 [create-pull-request] automated change (#2375)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-03-23 13:13:47 -05:00
code8buster
958d2cf630 Remove call to randomSeed() (#2374)
This function causes the new arduino-esp32 core to revert to the pseudorandom behavior specified in Arduino.
Calls to random() automatically use esp_random() if randomSeed or useRealRandomGenerator(false) aren't called.
Tentative fix for #2357
2023-03-23 12:05:12 -05:00
Ben Meadors
5cb1f96240 Use accelerometer to wake up screen (#2371)
* WIP accelerometer tinkering

* Debug logging

* RAK LIS3DH sensor

* Deconflict temperature sensor and LIS3DH

* Finishing up

* StateON

* Protobufs

* Default of none

* Formatting
2023-03-23 11:32:04 -05:00
Thomas Göttgens
78522e750c Merge pull request #2304 from meshtastic/ESP32C3-RISC
ESP32C3 RISC SOC
2023-03-21 17:21:31 +01:00
Thomas Göttgens
75db8c2d2e the target starts up and works for a few seconds before crashing. Good enough for others to continue the work :-) 2023-03-21 16:24:24 +01:00
Thomas Göttgens
91be22b341 Merge branch 'master' into ESP32C3-RISC 2023-03-21 09:31:30 +01:00
Thomas Göttgens
cc64c3d61a Merge branch 'master' into 2264-feature-check-for-low-heap-before-adding-to-nodedb-was-reboot-loop-heap-too-low 2023-03-21 09:30:54 +01:00
github-actions[bot]
36b00dba86 [create-pull-request] automated change (#2367)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-03-18 08:47:40 -05:00
Ben Meadors
3bb8cd7613 Merge branch 'master' into 2264-feature-check-for-low-heap-before-adding-to-nodedb-was-reboot-loop-heap-too-low 2023-03-18 07:26:44 -05:00
Thomas Göttgens
8db7316ae1 Merge branch 'master' into 2264-feature-check-for-low-heap-before-adding-to-nodedb-was-reboot-loop-heap-too-low 2023-03-12 20:22:46 +01:00
Thomas Göttgens
3c2e615650 Merge branch 'master' into ESP32C3-RISC 2023-03-12 20:22:38 +01:00
Thomas Göttgens
4573db4665 Merge branch 'master' into ESP32C3-RISC 2023-03-12 20:19:43 +01:00
Thomas Göttgens
d2c72fae00 Merge branch 'master' into 2264-feature-check-for-low-heap-before-adding-to-nodedb-was-reboot-loop-heap-too-low 2023-03-12 19:29:42 +01:00
Ben Meadors
2e3b86608a Merge branch 'master' into 2264-feature-check-for-low-heap-before-adding-to-nodedb-was-reboot-loop-heap-too-low 2023-03-10 19:50:41 -06:00
Thomas Göttgens
e0a6a37bef Merge branch '2264-feature-check-for-low-heap-before-adding-to-nodedb-was-reboot-loop-heap-too-low' of github.com:meshtastic/firmware into 2264-feature-check-for-low-heap-before-adding-to-nodedb-was-reboot-loop-heap-too-low 2023-03-10 21:39:33 +01:00
Thomas Göttgens
57fc9baafc cmsis is donning his own HardFault Handler 2023-03-10 21:39:21 +01:00
Thomas Göttgens
033e988e6f Merge branch 'master' into 2264-feature-check-for-low-heap-before-adding-to-nodedb-was-reboot-loop-heap-too-low 2023-03-10 19:38:14 +01:00
Thomas Göttgens
a95b6aff01 Merge branch 'master' into ESP32C3-RISC 2023-03-05 14:55:30 +01:00
Thomas Göttgens
b249970a12 add rudimentary exception decoder for RISC-V CPU 2023-03-05 14:55:12 +01:00
Thomas Göttgens
fe926eedba Merge branch 'ESP32C3-RISC' of github.com:meshtastic/firmware into ESP32C3-RISC 2023-03-04 23:17:56 +01:00
Thomas Göttgens
4355f51a90 fmt 2023-03-04 17:25:55 +01:00
Thomas Göttgens
ecd67f0a85 disable the frequency switcher for the C3 CPU... 2023-03-04 17:25:55 +01:00
Thomas Göttgens
0940c6462b Leaving this here in case someone ever needs int :-) 2023-03-04 17:25:55 +01:00
Thomas Göttgens
a47364f07b Merge branch 'master' into 2264-feature-check-for-low-heap-before-adding-to-nodedb-was-reboot-loop-heap-too-low 2023-03-04 17:24:16 +01:00
Thomas Göttgens
a3f1e53017 fmt 2023-02-24 09:53:25 +01:00
Thomas Göttgens
0243922d64 Merge branch 'ESP32C3-RISC' of github.com:meshtastic/firmware into ESP32C3-RISC 2023-02-24 09:32:43 +01:00
Thomas Göttgens
baeb2807a4 disable the frequency switcher for the C3 CPU... 2023-02-24 09:32:31 +01:00
Thomas Göttgens
9a8bfa113d Leaving this here in case someone ever needs int :-) 2023-02-23 22:55:50 +01:00
Thomas Göttgens
82b14fe07c Leaving this here in case someone ever needs int :-) 2023-02-23 22:54:07 +01:00
Ben Meadors
48a407bf5c Merge branch 'master' into 2264-feature-check-for-low-heap-before-adding-to-nodedb-was-reboot-loop-heap-too-low 2023-02-23 07:10:41 -06:00
Thomas Göttgens
2475debb2a Merge branch 'master' into 2264-feature-check-for-low-heap-before-adding-to-nodedb-was-reboot-loop-heap-too-low 2023-02-22 10:15:09 +01:00
Thomas Göttgens
568899031d Check if there's something there before we free it 2023-02-22 10:07:03 +01:00
Thomas Göttgens
f1c457f0c3 tryfix #2228 as suggested by @mverch67 2023-02-22 10:07:03 +01:00
Ben Meadors
c8399b7256 Remove extra 2023-02-22 10:07:03 +01:00
github-actions[bot]
63005a94fd [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-22 10:07:03 +01:00
Ben Meadors
9b4a59f92d Add da explora 2023-02-22 10:07:03 +01:00
GUVWAF
2472d0947f RadioLib's startChannel returns LORA_DETECTED for SX126x and SX128x (#2293) 2023-02-22 10:07:03 +01:00
Ben Meadors
a92b2ec6ca Trunk fix 2023-02-22 10:07:03 +01:00
Ben Meadors
548bec026a Trunk fmt 2023-02-22 10:07:03 +01:00
Krezalis
ce882b389a Update Screen.h (#2285)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-02-22 10:07:03 +01:00
Krezalis
25fd9d2d1d Add Ukrainian symbols (#2286)
* Update Screen.cpp

* Add files via upload

* Update Screen.cpp

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-02-22 10:07:03 +01:00
GUVWAF
83a201fe86 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-22 10:07:03 +01:00
Ben Meadors
462ee3d921 Missed a reference 2023-02-22 10:07:03 +01:00
Ben Meadors
0104246067 Remove pico from build for now 2023-02-22 10:07:03 +01:00
Ben Meadors
3f5c0cb6ac Don't auto set to default primary channel 2023-02-22 10:07:03 +01:00
Neil Hao
fa371bc844 Update extensions.json 2023-02-22 10:07:03 +01:00
neil
090f42f51f 'nano-g1-explorer' 2023-02-22 10:07:03 +01:00
thebentern
c2ff6f2f7c [create-pull-request] automated change 2023-02-22 10:07:03 +01:00
Thomas Göttgens
181832aedd Merge pull request #2282 from meshtastic/master
Catch up
2023-02-17 12:32:33 +01:00
Thomas Göttgens
4967a16abe - Abstract the memory stats into its own class.
- Fix a bug with debug mqtt
- nrf52 needs more love, there's a strange error while linking. Help appreciated
2023-02-17 12:31:51 +01:00
Thomas Göttgens
e2f5e9206d 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:40:47 +01:00
Thomas Göttgens
57b8e3732e Update to Espressif32 Platform 6.0 and ESP-IDF 5.0 2023-02-10 01:40:47 +01:00
Ben Meadors
f0d27f896a Add changed back 2023-02-10 01:40:47 +01:00
Ben Meadors
e74b180655 Remove setOwner's business logic for licensed operation 2023-02-10 01:40:47 +01:00
Ben Meadors
88a44eede0 Rebroadcast mode to local_only for hams 2023-02-10 01:40:47 +01:00
119 changed files with 2623 additions and 304 deletions

View File

@@ -42,6 +42,7 @@ jobs:
uses: ./.github/actions/setup-base
- name: Trunk Check
if: ${{ github.event_name != 'workflow_dispatch' }}
uses: trunk-io/trunk-action@v1
- name: Check ${{ matrix.board }}

3
.trunk/configs/.flake8 Normal file
View File

@@ -0,0 +1,3 @@
# Autoformatter friendly flake8 config (all formatting rules disabled)
[flake8]
extend-ignore = D1, D2, E1, E2, E3, E501, W1, W2, W3, W5

View File

@@ -0,0 +1,2 @@
[settings]
profile=black

View File

@@ -0,0 +1,10 @@
rules:
quoted-strings:
required: only-when-needed
extra-allowed: ["{|}"]
empty-values:
forbid-in-block-mappings: true
forbid-in-flow-mappings: true
key-duplicates: {}
octal-values:
forbid-implicit-octal: true

5
.trunk/configs/ruff.toml Normal file
View File

@@ -0,0 +1,5 @@
# Generic, formatter-friendly config.
select = ["B", "D3", "D4", "E", "F"]
# Never enforce `E501` (line length violations). This should be handled by formatters.
ignore = ["E501"]

View File

@@ -1,18 +1,31 @@
version: 0.1
cli:
version: 1.3.1
version: 1.7.0
plugins:
sources:
- id: trunk
ref: v0.0.8
ref: v0.0.14
uri: https://github.com/trunk-io/plugins
lint:
enabled:
- ruff@0.0.260
- yamllint@1.30.0
- isort@5.12.0
- markdownlint@0.33.0
- oxipng@8.0.0
- svgo@3.0.2
- actionlint@1.6.23
- flake8@6.0.0
- hadolint@2.12.0
- shfmt@3.5.0
- shellcheck@0.9.0
- black@23.3.0
- git-diff-check
- gitleaks@8.15.2
- gitleaks@8.16.2
- clang-format@14.0.0
- prettier@2.8.3
- prettier@2.8.7
disabled:
- taplo@0.7.0
- shellcheck@0.9.0
- shfmt@3.5.0
- oxipng@8.0.0
@@ -22,7 +35,8 @@ lint:
- svgo@3.0.2
runtimes:
enabled:
- go@1.18.3
- python@3.10.8
- go@1.19.5
- node@18.12.1
actions:
disabled:

View File

@@ -35,7 +35,7 @@ lib_deps =
https://github.com/meshtastic/esp32_https_server.git#23665b3adc080a311dcbb586ed5941b5f94d6ea2
h2zero/NimBLE-Arduino@^1.4.0
https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6
caveman99/ESP32 Codec2@^1.0.1
https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f
lib_ignore =
segger_rtt

44
arch/esp32/esp32c3.ini Normal file
View File

@@ -0,0 +1,44 @@
[esp32c3_base]
extends = arduino_base
platform = platformio/espressif32@^6.1.0
build_src_filter =
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2040> -<mesh/eth/>
upload_speed = 961200
monitor_speed = 115200
debug_init_break = tbreak setup
monitor_filters = esp32_c3_exception_decoder
board_build.filesystem = littlefs
# Remove -DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL for low level BLE logging.
# See library directory for BLE logging possible values: .pio/libdeps/tbeam/NimBLE-Arduino/src/log_common/log_common.h
# This overrides the BLE logging default of LOG_LEVEL_INFO (1) from: .pio/libdeps/tbeam/NimBLE-Arduino/src/esp_nimble_cfg.h
build_flags =
${arduino_base.build_flags}
-Wall
-Wextra
-Isrc/platform/esp32
-std=c++11
-DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG
-DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
-DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL
-DCONFIG_BT_NIMBLE_ENABLED
-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}
${networking_base.lib_deps}
${environmental_base.lib_deps}
https://github.com/meshtastic/esp32_https_server.git#23665b3adc080a311dcbb586ed5941b5f94d6ea2
h2zero/NimBLE-Arduino@^1.4.0
https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6
https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f
lib_ignore =
segger_rtt
ESP32 BLE Arduino
; customize the partition table
; http://docs.platformio.org/en/latest/platforms/espressif32.html#partition-tables
board_build.partitions = partition-table.csv

View File

@@ -35,7 +35,7 @@ lib_deps =
${environmental_base.lib_deps}
https://github.com/meshtastic/esp32_https_server.git#23665b3adc080a311dcbb586ed5941b5f94d6ea2
https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6
caveman99/ESP32 Codec2@^1.0.1
https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f
lib_ignore =
segger_rtt

View File

@@ -35,7 +35,7 @@ lib_deps =
https://github.com/meshtastic/esp32_https_server.git#23665b3adc080a311dcbb586ed5941b5f94d6ea2
h2zero/NimBLE-Arduino@^1.4.0
https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6
caveman99/ESP32 Codec2@^1.0.1
https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f
lib_ignore =
segger_rtt

38
bin/generate_ci_matrix.py Executable file
View File

@@ -0,0 +1,38 @@
#!/usr/bin/env python
"""Generate the CI matrix"""
import configparser
import json
import os
import sys
rootdir = "variants/"
options = sys.argv[1:]
outlist = []
if len(options) < 1:
print(json.dumps(outlist))
exit()
for subdir, dirs, files in os.walk(rootdir):
for file in files:
if file == "platformio.ini":
config = configparser.ConfigParser()
config.read(subdir + "/" + file)
for c in config.sections():
if c.startswith("env:"):
section = config[c].name[4:]
if "extends" in config[config[c].name]:
if config[config[c].name]["extends"] == options[0] + "_base":
if "board_level" in config[config[c].name]:
if (
config[config[c].name]["board_level"] == "extra"
) & ("extra" in options):
outlist.append(section)
else:
outlist.append(section)
print(json.dumps(outlist))

View File

@@ -1,5 +1 @@
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' *
cd protobufs && ..\nanopb-0.4.7\generator-bin\protoc.exe --experimental_allow_proto3_optional --nanopb_out=-v:..\src\mesh\generated -I=..\protobufs ..\protobufs\meshtastic\*.proto

View File

@@ -8,7 +8,7 @@ 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 meshtastic/*.proto
../nanopb-0.4.7/generator-bin/protoc --nanopb_out=-v:../src/mesh/generated/ -I=../protobufs meshtastic/*.proto --experimental_allow_proto3_optional
# cd ../src/mesh/generated/meshtastic
# sed -i 's/#include "meshtastic/#include "./g' -- *

View File

@@ -0,0 +1,41 @@
{
"build": {
"arduino": {
"ldscript": "esp32s3_out.ld",
"memory_type": "qio_opi"
},
"core": "esp32",
"extra_flags": [
"-DBOARD_HAS_PSRAM",
"-DARDUINO_USB_CDC_ON_BOOT=1",
"-DARDUINO_USB_MODE=0",
"-DARDUINO_RUNNING_CORE=1",
"-DARDUINO_EVENT_RUNNING_CORE=0"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"hwids": [["0x303A", "0x1001"]],
"mcu": "esp32s3",
"variant": "my-esp32s3-diy-oled"
},
"connectivity": ["wifi"],
"debug": {
"default_tool": "esp-builtin",
"onboard_tools": ["esp-builtin"],
"openocd_target": "esp32s3.cfg"
},
"frameworks": ["arduino", "espidf"],
"name": "Clone ESP32-S3-DevKitC-1 v1.1 (16 MB FLASH, 8 MB PSRAM)",
"upload": {
"flash_size": "16MB",
"maximum_ram_size": 327680,
"maximum_size": 16777216,
"use_1200bps_touch": true,
"wait_for_upload_port": true,
"require_upload_port": true,
"speed": 921600
},
"url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/hw-reference/esp32s3/user-guide-devkitc-1.html",
"vendor": "Espressif"
}

View File

@@ -0,0 +1,41 @@
{
"build": {
"arduino": {
"ldscript": "esp32s3_out.ld",
"memory_type": "qio_opi"
},
"core": "esp32",
"extra_flags": [
"-DBOARD_HAS_PSRAM",
"-DARDUINO_USB_CDC_ON_BOOT=1",
"-DARDUINO_USB_MODE=0",
"-DARDUINO_RUNNING_CORE=1",
"-DARDUINO_EVENT_RUNNING_CORE=0"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"hwids": [["0x303A", "0x1001"]],
"mcu": "esp32s3",
"variant": "my_esp32s3_diy_eink"
},
"connectivity": ["wifi"],
"debug": {
"default_tool": "esp-builtin",
"onboard_tools": ["esp-builtin"],
"openocd_target": "esp32s3.cfg"
},
"frameworks": ["arduino", "espidf"],
"name": "Clone ESP32-S3-DevKitC-1 v1.1 (16 MB FLASH, 8 MB PSRAM)",
"upload": {
"flash_size": "16MB",
"maximum_ram_size": 327680,
"maximum_size": 16777216,
"use_1200bps_touch": true,
"wait_for_upload_port": true,
"require_upload_port": true,
"speed": 921600
},
"url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/hw-reference/esp32s3/user-guide-devkitc-1.html",
"vendor": "Espressif"
}

38
bpi_picow_esp32_s3.json Normal file
View File

@@ -0,0 +1,38 @@
{
"build": {
"arduino": {
"ldscript": "esp32s3_out.ld"
},
"core": "esp32",
"extra_flags": [
"-DARDUINO_USB_CDC_ON_BOOT=1",
"-DARDUINO_USB_MODE=0",
"-DARDUINO_RUNNING_CORE=1",
"-DARDUINO_EVENT_RUNNING_CORE=1",
"-DBOARD_HAS_PSRAM"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "dio",
"hwids": [["0x303A", "0x1001"]],
"mcu": "esp32s3",
"variant": "bpi_picow_esp32_s3"
},
"connectivity": ["wifi"],
"debug": {
"openocd_target": "esp32s3.cfg"
},
"frameworks": ["arduino", "espidf"],
"name": "BPI-PicoW-S3 (8 MB FLASH, 2 MB PSRAM)",
"upload": {
"flash_size": "8MB",
"maximum_ram_size": 327680,
"maximum_size": 8388608,
"use_1200bps_touch": true,
"wait_for_upload_port": true,
"require_upload_port": true,
"speed": 921600
},
"url": "https://wiki.banana-pi.org/BPI-PicoW-S3",
"vendor": "BPI"
}

View File

@@ -0,0 +1,155 @@
# Copyright (c) 2014-present PlatformIO <contact@platformio.org>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import re
import subprocess
import sys
from platformio.project.exception import PlatformioException
from platformio.public import (
DeviceMonitorFilterBase,
load_build_metadata,
)
# By design, __init__ is called inside miniterm and we can't pass context to it.
# pylint: disable=attribute-defined-outside-init
IS_WINDOWS = sys.platform.startswith("win")
class Esp32C3ExceptionDecoder(DeviceMonitorFilterBase):
NAME = "esp32_c3_exception_decoder"
PCADDR_PATTERN = re.compile(r'0x4[0-9a-f]{7}', re.IGNORECASE)
def __call__(self):
self.buffer = ""
self.pcaddr_re = self.PCADDR_PATTERN
self.firmware_path = None
self.addr2line_path = None
self.enabled = self.setup_paths()
if self.config.get("env:" + self.environment, "build_type") != "debug":
print(
"""
Please build project in debug configuration to get more details about an exception.
See https://docs.platformio.org/page/projectconf/build_configurations.html
"""
)
return self
def setup_paths(self):
self.project_dir = os.path.abspath(self.project_dir)
try:
data = load_build_metadata(self.project_dir, self.environment)
self.firmware_path = data["prog_path"]
if not os.path.isfile(self.firmware_path):
sys.stderr.write(
"%s: disabling, firmware at %s does not exist, rebuild the project?\n"
% (self.__class__.__name__, self.firmware_path)
)
return False
if self.addr2line_path is None:
cc_path = data.get("cc_path", "")
if "-gcc" in cc_path:
self.addr2line_path = cc_path.replace("-gcc", "-addr2line")
else:
sys.stderr.write(
"%s: disabling, failed to find addr2line.\n"
% self.__class__.__name__
)
return False
if not os.path.isfile(self.addr2line_path):
sys.stderr.write(
"%s: disabling, addr2line at %s does not exist\n"
% (self.__class__.__name__, self.addr2line_path)
)
return False
return True
except PlatformioException as e:
sys.stderr.write(
"%s: disabling, exception while looking for addr2line: %s\n"
% (self.__class__.__name__, e)
)
return False
def rx(self, text):
if not self.enabled:
return text
last = 0
while True:
idx = text.find("\n", last)
if idx == -1:
if len(self.buffer) < 4096:
self.buffer += text[last:]
break
line = text[last:idx]
if self.buffer:
line = self.buffer + line
self.buffer = ""
last = idx + 1
# Output each trace on a separate line below ours
# Logic identical to https://github.com/espressif/esp-idf/blob/master/tools/idf_monitor_base/logger.py#L131
for m in re.finditer(self.pcaddr_re, line):
if m is None:
continue
trace = self.get_backtrace(m)
if len(trace) != "":
text = text[: last] + trace + text[last :]
last += len(trace)
return text
def get_backtrace(self, match):
trace = "\n"
enc = "mbcs" if IS_WINDOWS else "utf-8"
args = [self.addr2line_path, u"-fipC", u"-e", self.firmware_path]
try:
addr = match.group()
output = (
subprocess.check_output(args + [addr])
.decode(enc)
.strip()
)
output = output.replace(
"\n", "\n "
) # newlines happen with inlined methods
output = self.strip_project_dir(output)
# Output the trace in yellow color so that it is easier to spot
trace += "\033[33m=> %s: %s\033[0m\n" % (addr, output)
except subprocess.CalledProcessError as e:
sys.stderr.write(
"%s: failed to call %s: %s\n"
% (self.__class__.__name__, self.addr2line_path, e)
)
return trace
def strip_project_dir(self, trace):
while True:
idx = trace.find(self.project_dir)
if idx == -1:
break
trace = trace[:idx] + trace[idx + len(self.project_dir) + 1 :]
return trace

View File

@@ -66,7 +66,9 @@ lib_deps =
https://github.com/meshtastic/ArduinoThread.git#72921ac222eed6f526ba1682023cee290d9aa1b3
nanopb/Nanopb@^0.4.7
erriez/ErriezCRC32@^1.0.1
jgromes/RadioLib@^5.7.0
; temp: do this till > 5.7.0 release to keep (some) SX1262 and SX1280 working - resolves -705 error during init
https://github.com/jgromes/RadioLib.git#45c5859338590b7eede23cb2f95284c3fb0cf08e
; jgromes/RadioLib@^5.7.0
; Used for the code analysis in PIO Home / Inspect
check_tool = cppcheck
@@ -83,7 +85,7 @@ lib_deps =
${env.lib_deps}
mprograms/QMC5883LCompass@^1.1.1
end2endzone/NonBlockingRTTTL@^1.3.0
https://github.com/meshtastic/SparkFun_ATECCX08a_Arduino_Library.git#52b5282639d08a8cbd4b748363089eed6102dc76
https://github.com/meshtastic/SparkFun_ATECCX08a_Arduino_Library.git#5cf62b36c6f30bc72a07bdb2c11fc9a22d1e31da
build_flags = ${env.build_flags} -Os -DRADIOLIB_SPI_PARANOID=0
build_src_filter = ${env.build_src_filter} -<platform/portduino/>
@@ -103,7 +105,7 @@ lib_deps =
adafruit/Adafruit Unified Sensor@^1.1.9
adafruit/Adafruit BMP280 Library@^2.6.6
adafruit/Adafruit BME280 Library@^2.2.2
adafruit/Adafruit BME680 Library@^2.0.1
https://github.com/meshtastic/BSEC-Arduino-library.git#452f9a7ffa8b53e1debe2c454fe375dfad98b507
adafruit/Adafruit MCP9808 Library@^2.0.0
adafruit/Adafruit INA260 Library@^1.5.0
adafruit/Adafruit INA219@^1.2.0
@@ -111,3 +113,5 @@ lib_deps =
adafruit/Adafruit LPS2X@^2.0.4
adafruit/Adafruit SHT31 Library@^2.2.0
adafruit/Adafruit PM25 AQI Sensor@^1.0.6
adafruit/Adafruit MPU6050@^2.2.4
adafruit/Adafruit LIS3DH@^1.2.4

92
src/AccelerometerThread.h Normal file
View File

@@ -0,0 +1,92 @@
#include "PowerFSM.h"
#include "concurrency/OSThread.h"
#include "configuration.h"
#include "main.h"
#include "power.h"
#include <Adafruit_LIS3DH.h>
#include <Adafruit_MPU6050.h>
#define ACCELEROMETER_CHECK_INTERVAL_MS 100
#define ACCELEROMETER_CLICK_THRESHOLD 40
namespace concurrency
{
class AccelerometerThread : public concurrency::OSThread
{
public:
AccelerometerThread(ScanI2C::DeviceType type = ScanI2C::DeviceType::NONE) : OSThread("AccelerometerThread")
{
if (accelerometer_found.port == ScanI2C::I2CPort::NO_I2C) {
LOG_DEBUG("AccelerometerThread disabling due to no sensors found\n");
disable();
return;
}
if (!config.display.wake_on_tap_or_motion && !config.device.double_tap_as_button_press) {
LOG_DEBUG("AccelerometerThread disabling due to no interested configurations\n");
disable();
return;
}
accleremoter_type = type;
LOG_DEBUG("AccelerometerThread initializing\n");
if (accleremoter_type == ScanI2C::DeviceType::MPU6050 && mpu.begin(accelerometer_found.address)) {
LOG_DEBUG("MPU6050 initializing\n");
// setup motion detection
mpu.setHighPassFilter(MPU6050_HIGHPASS_0_63_HZ);
mpu.setMotionDetectionThreshold(1);
mpu.setMotionDetectionDuration(20);
mpu.setInterruptPinLatch(true); // Keep it latched. Will turn off when reinitialized.
mpu.setInterruptPinPolarity(true);
} else if (accleremoter_type == ScanI2C::DeviceType::LIS3DH && lis.begin(accelerometer_found.address)) {
LOG_DEBUG("LIS3DH initializing\n");
lis.setRange(LIS3DH_RANGE_2_G);
// Adjust threshhold, higher numbers are less sensitive
lis.setClick(config.device.double_tap_as_button_press ? 2 : 1, ACCELEROMETER_CLICK_THRESHOLD);
}
}
protected:
int32_t runOnce() override
{
canSleep = true; // Assume we should not keep the board awake
if (accleremoter_type == ScanI2C::DeviceType::MPU6050 && mpu.getMotionInterruptStatus()) {
wakeScreen();
} else if (accleremoter_type == ScanI2C::DeviceType::LIS3DH && lis.getClick() > 0) {
uint8_t click = lis.getClick();
if (!config.device.double_tap_as_button_press) {
wakeScreen();
}
if (config.device.double_tap_as_button_press && (click & 0x20)) {
buttonPress();
return 500;
}
}
return ACCELEROMETER_CHECK_INTERVAL_MS;
}
private:
void wakeScreen()
{
if (powerFSM.getState() == &stateDARK) {
LOG_INFO("Tap or motion detected. Turning on screen\n");
powerFSM.trigger(EVENT_INPUT);
}
}
void buttonPress()
{
LOG_DEBUG("Double-tap detected. Firing button press\n");
powerFSM.trigger(EVENT_PRESS);
}
ScanI2C::DeviceType accleremoter_type;
Adafruit_MPU6050 mpu;
Adafruit_LIS3DH lis;
};
} // namespace concurrency

View File

@@ -45,10 +45,10 @@ class ButtonThread : public concurrency::OSThread
ButtonThread() : OSThread("Button")
{
#ifdef BUTTON_PIN
userButton = OneButton(BUTTON_PIN, true, true);
userButton = OneButton(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN, true, true);
#ifdef INPUT_PULLUP_SENSE
// Some platforms (nrf52) have a SENSE variant which allows wake from sleep - override what OneButton did
pinMode(BUTTON_PIN, INPUT_PULLUP_SENSE);
pinMode(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN, INPUT_PULLUP_SENSE);
#endif
userButton.attachClick(userButtonPressed);
userButton.setClickTicks(300);
@@ -57,7 +57,7 @@ class ButtonThread : public concurrency::OSThread
userButton.attachMultiClick(userButtonMultiPressed);
userButton.attachLongPressStart(userButtonPressedLongStart);
userButton.attachLongPressStop(userButtonPressedLongStop);
wakeOnIrq(BUTTON_PIN, FALLING);
wakeOnIrq(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN, FALLING);
#endif
#ifdef BUTTON_PIN_ALT
userButtonAlt = OneButton(BUTTON_PIN_ALT, true, true);
@@ -115,7 +115,9 @@ 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 (((config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN) !=
moduleConfig.canned_message.inputbroker_pin_press) ||
!moduleConfig.canned_message.enabled) {
powerFSM.trigger(EVENT_PRESS);
}
#endif
@@ -124,13 +126,8 @@ class ButtonThread : public concurrency::OSThread
{
// LOG_DEBUG("Long press!\n");
// If user button is held down for 5 seconds, shutdown the device.
if ((millis() - longPressTime > 5 * 1000) && (longPressTime > 0)) {
#ifdef HAS_PMU
if (pmu_found == true) {
setLed(false);
power->shutdown();
}
#elif defined(ARCH_NRF52) || defined(ARCH_ESP32)
if ((millis() - longPressTime > 5000) && (longPressTime > 0)) {
#if defined(ARCH_NRF52) || defined(ARCH_ESP32)
// Do actual shutdown when button released, otherwise the button release
// may wake the board immediatedly.
if ((!shutdown_on_long_stop) && (millis() > 30 * 1000)) {

View File

@@ -34,6 +34,7 @@ bool copyFile(const char *from, const char *to)
f2.write(cbuffer, i);
}
f2.flush();
f2.close();
f1.close();
return true;

View File

@@ -160,8 +160,18 @@ class AnalogBatteryLevel : public HasBatteryLevel
/// If we see a battery voltage higher than physics allows - assume charger is pumping
/// in power
/// On some boards we don't have the power management chip (like AXPxxxx)
/// so we use EXT_PWR_DETECT GPIO pin to detect external power source
virtual bool isVbusIn() override
{
#ifdef EXT_PWR_DETECT
// if external powered that pin will be pulled up
if (digitalRead(EXT_PWR_DETECT) == HIGH) {
return true;
}
// if it's not HIGH - check the battery
#endif
return getBattVoltage() > chargingVolt;
}
@@ -202,12 +212,16 @@ Power::Power() : OSThread("Power")
statusHandler = {};
low_voltage_counter = 0;
#ifdef DEBUG_HEAP
lastheap = ESP.getFreeHeap();
lastheap = memGet.getFreeHeap();
#endif
}
bool Power::analogInit()
{
#ifdef EXT_PWR_DETECT
pinMode(EXT_PWR_DETECT, INPUT);
#endif
#ifdef BATTERY_PIN
LOG_DEBUG("Using analog input %d for battery level\n", BATTERY_PIN);
@@ -263,12 +277,11 @@ void Power::shutdown()
LOG_INFO("Shutting down\n");
#ifdef HAS_PMU
if (PMU) {
if (pmu_found == true) {
PMU->setChargingLedMode(XPOWERS_CHG_LED_OFF);
PMU->shutdown();
}
#endif
#if defined(ARCH_NRF52) || defined(ARCH_ESP32)
#elif defined(ARCH_NRF52) || defined(ARCH_ESP32)
#ifdef PIN_LED1
ledOff(PIN_LED1);
#endif
@@ -314,7 +327,7 @@ void Power::readPowerStatus()
powerStatus2.getIsCharging(), powerStatus2.getBatteryVoltageMv(), powerStatus2.getBatteryChargePercent());
newStatus.notifyObservers(&powerStatus2);
#ifdef DEBUG_HEAP
if (lastheap != ESP.getFreeHeap()) {
if (lastheap != memGet.getFreeHeap()) {
LOG_DEBUG("Threads running:");
int running = 0;
for (int i = 0; i < MAX_THREADS; i++) {
@@ -325,9 +338,9 @@ void Power::readPowerStatus()
}
}
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));
lastheap = ESP.getFreeHeap();
LOG_DEBUG("Heap status: %d/%d bytes free (%d), running %d/%d threads\n", memGet.getFreeHeap(), memGet.getHeapSize(),
memGet.getFreeHeap() - lastheap, running, concurrency::mainController.size(false));
lastheap = memGet.getFreeHeap();
}
#ifdef DEBUG_HEAP_MQTT
if (mqtt) {
@@ -336,41 +349,41 @@ void Power::readPowerStatus()
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);
auto newHeap = memGet.getFreeHeap();
std::string heapTopic =
(*moduleConfig.mqtt.root ? moduleConfig.mqtt.root : "msh") + std::string("/2/heap/") + std::string(mac);
std::string heapString = std::to_string(newHeap);
mqtt->pubSub.publish(heapTopic.c_str(), heapString.c_str(), false);
// auto fragHeap = ESP.getHeapFragmentation();
auto wifiRSSI = WiFi.RSSI();
heapTopic = "msh/2/wifi/" + std::string(mac);
std::string wifiTopic =
(*moduleConfig.mqtt.root ? moduleConfig.mqtt.root : "msh") + std::string("/2/wifi/") + std::string(mac);
std::string wifiString = std::to_string(wifiRSSI);
mqtt->pubSub.publish(heapTopic.c_str(), wifiString.c_str(), false);
mqtt->pubSub.publish(wifiTopic.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
// Supect fluctuating voltage on the RAK4631 to force it to deep sleep even if battery is at 85% after only a few days
#ifdef ARCH_NRF52
// If we have a battery at all and it is less than 10% full, force deep sleep if we have more than 10 low readings in a
// row
if (powerStatus2.getHasBattery() && !powerStatus2.getHasUSB()) {
if (batteryLevel->getBattVoltage() < MIN_BAT_MILLIVOLTS) {
low_voltage_counter++;
LOG_DEBUG("Warning RAK4631 Low voltage counter: %d/10\n", low_voltage_counter);
LOG_DEBUG("Low voltage counter: %d/10\n", low_voltage_counter);
if (low_voltage_counter > 10) {
#ifdef ARCH_NRF52
// We can't trigger deep sleep on NRF52, it's freezing the board
// powerFSM.trigger(EVENT_LOW_BATTERY);
LOG_DEBUG("Low voltage detected, but not triggering deep sleep\n");
#else
LOG_INFO("Low voltage detected, triggering deep sleep\n");
powerFSM.trigger(EVENT_LOW_BATTERY);
#endif
}
} else {
low_voltage_counter = 0;
}
}
#else
// If we have a battery at all and it is less than 10% full, force deep sleep
if (powerStatus2.getHasBattery() && !powerStatus2.getHasUSB() && batteryLevel->getBattVoltage() < MIN_BAT_MILLIVOLTS)
powerFSM.trigger(EVENT_LOW_BATTERY);
#endif
} else {
// No power sensing on this board - tell everyone else we have no idea what is happening
const PowerStatus powerStatus3 = PowerStatus(OptUnknown, OptUnknown, OptUnknown, -1, -1);
@@ -524,11 +537,41 @@ bool Power::axpChipInit()
// Set up the charging voltage
PMU->setChargeTargetVoltage(XPOWERS_AXP192_CHG_VOL_4V2);
} else if (PMU->getChipModel() == XPOWERS_AXP2101) {
// t-beam s3 core
/*The alternative version of T-Beam 1.1 differs from T-Beam V1.1 in that it uses an AXP2101 power chip*/
#if (HW_VENDOR == meshtastic_HardwareModel_TBEAM)
// Unuse power channel
PMU->disablePowerOutput(XPOWERS_DCDC2);
PMU->disablePowerOutput(XPOWERS_DCDC3);
PMU->disablePowerOutput(XPOWERS_DCDC4);
PMU->disablePowerOutput(XPOWERS_DCDC5);
PMU->disablePowerOutput(XPOWERS_ALDO1);
PMU->disablePowerOutput(XPOWERS_ALDO4);
PMU->disablePowerOutput(XPOWERS_BLDO1);
PMU->disablePowerOutput(XPOWERS_BLDO2);
PMU->disablePowerOutput(XPOWERS_DLDO1);
PMU->disablePowerOutput(XPOWERS_DLDO2);
// GNSS RTC PowerVDD 3300mV
PMU->setPowerChannelVoltage(XPOWERS_VBACKUP, 3300);
PMU->enablePowerOutput(XPOWERS_VBACKUP);
// ESP32 VDD 3300mV
// ! No need to set, automatically open , Don't close it
// PMU->setPowerChannelVoltage(XPOWERS_DCDC1, 3300);
// PMU->setProtectedChannel(XPOWERS_DCDC1);
// LoRa VDD 3300mV
PMU->setPowerChannelVoltage(XPOWERS_ALDO2, 3300);
PMU->enablePowerOutput(XPOWERS_ALDO2);
// GNSS VDD 3300mV
PMU->setPowerChannelVoltage(XPOWERS_ALDO3, 3300);
PMU->enablePowerOutput(XPOWERS_ALDO3);
#elif (HW_VENDOR == meshtastic_HardwareModel_LILYGO_TBEAM_S3_CORE)
// t-beam s3 core
/**
* 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
@@ -571,6 +614,8 @@ bool Power::axpChipInit()
PMU->disablePowerOutput(XPOWERS_DLDO2); // Invalid power channel, it does not exist
PMU->disablePowerOutput(XPOWERS_VBACKUP);
#endif
// disable all axp chip interrupt
PMU->disableIRQ(XPOWERS_AXP2101_ALL_IRQ);
@@ -683,4 +728,4 @@ bool Power::axpChipInit()
#else
return false;
#endif
}
}

View File

@@ -26,6 +26,9 @@ static bool isPowered()
1) If we're powered up and there's no battery, we must be getting power externally. (because we'd be dead otherwise)
2) If we detect USB power from the power management chip, we must be getting power externally.
3) On some boards we don't have the power management chip (like AXPxxxx) so we use EXT_PWR_DETECT GPIO pin to detect
external power source (see `isVbusIn()` in `Power.cpp`)
*/
return !isPowerSavingMode && powerStatus && (!powerStatus->getHasBattery() || powerStatus->getHasUSB());
}
@@ -66,11 +69,11 @@ static void lsIdle()
// Do we have more sleeping to do?
if (secsSlept < config.power.ls_secs) {
// Briefly come out of sleep long enough to blink the led once every few seconds
uint32_t sleepTime = 30;
// If some other service would stall sleep, don't let sleep happen yet
if (doPreflightSleep()) {
// Briefly come out of sleep long enough to blink the led once every few seconds
uint32_t sleepTime = 30;
setLed(false); // Never leave led on while in light sleep
esp_sleep_source_t wakeCause2 = doLightSleep(sleepTime * 1000LL);
@@ -96,12 +99,11 @@ static void lsIdle()
LOG_INFO("wakeCause2 %d\n", wakeCause2);
#ifdef BUTTON_PIN
bool pressed = !digitalRead(BUTTON_PIN);
bool pressed = !digitalRead(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN);
#else
bool pressed = false;
#endif
if (pressed) // If we woke because of press, instead generate a PRESS event.
{
if (pressed) { // If we woke because of press, instead generate a PRESS event.
powerFSM.trigger(EVENT_PRESS);
} else {
// Otherwise let the NB state handle the IRQ (and that state will handle stuff like IRQs etc)
@@ -169,7 +171,11 @@ static void powerEnter()
} else {
screen->setOn(true);
setBluetoothEnable(true);
screen->print("Powered...\n");
// within enter() the function getState() returns the state we came from
if (strcmp(powerFSM.getState()->name, "BOOT") != 0 && strcmp(powerFSM.getState()->name, "POWER") != 0 &&
strcmp(powerFSM.getState()->name, "DARK") != 0) {
screen->print("Powered...\n");
}
}
}
@@ -186,7 +192,8 @@ static void powerExit()
{
screen->setOn(true);
setBluetoothEnable(true);
screen->print("Unpowered...\n");
if (!isPowered())
screen->print("Unpowered...\n");
}
static void onEnter()
@@ -194,17 +201,6 @@ static void onEnter()
LOG_INFO("Enter state: ON\n");
screen->setOn(true);
setBluetoothEnable(true);
static uint32_t lastPingMs;
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 (displayedNodeNum)
service.sendNetworkPing(displayedNodeNum, true); // Refresh the currently displayed node
lastPingMs = now;
}
}
static void onIdle()
@@ -257,7 +253,7 @@ void PowerFSM_setup()
// Handle press events - note: we ignore button presses when in API mode
powerFSM.add_transition(&stateLS, &stateON, EVENT_PRESS, NULL, "Press");
powerFSM.add_transition(&stateNB, &stateON, EVENT_PRESS, NULL, "Press");
powerFSM.add_transition(&stateDARK, &stateON, EVENT_PRESS, NULL, "Press");
powerFSM.add_transition(&stateDARK, isPowered() ? &statePOWER : &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,
@@ -299,10 +295,10 @@ void PowerFSM_setup()
powerFSM.add_transition(&stateON, &stateON, EVENT_NODEDB_UPDATED, NULL, "NodeDB update");
// Show the received text message
powerFSM.add_transition(&stateLS, &stateON, EVENT_RECEIVED_TEXT_MSG, NULL, "Received text");
powerFSM.add_transition(&stateNB, &stateON, EVENT_RECEIVED_TEXT_MSG, NULL, "Received text");
powerFSM.add_transition(&stateDARK, &stateON, EVENT_RECEIVED_TEXT_MSG, NULL, "Received text");
powerFSM.add_transition(&stateON, &stateON, EVENT_RECEIVED_TEXT_MSG, NULL, "Received text"); // restarts the sleep timer
powerFSM.add_transition(&stateLS, &stateON, EVENT_RECEIVED_MSG, NULL, "Received text");
powerFSM.add_transition(&stateNB, &stateON, EVENT_RECEIVED_MSG, NULL, "Received text");
powerFSM.add_transition(&stateDARK, &stateON, EVENT_RECEIVED_MSG, NULL, "Received text");
powerFSM.add_transition(&stateON, &stateON, EVENT_RECEIVED_MSG, NULL, "Received text"); // restarts the sleep timer
}
// If we are not in statePOWER but get a serial connection, suppress sleep (and keep the screen on) while connected
@@ -330,6 +326,12 @@ void PowerFSM_setup()
powerFSM.add_timed_transition(&stateON, &stateDARK,
getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs), NULL,
"Screen-on timeout");
powerFSM.add_timed_transition(&statePOWER, &stateDARK,
getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs), NULL,
"Screen-on timeout");
powerFSM.add_timed_transition(&stateDARK, &stateDARK,
getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs), NULL,
"Screen-on timeout");
#ifdef ARCH_ESP32
State *lowPowerState = &stateLS;
@@ -351,4 +353,4 @@ void PowerFSM_setup()
#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

@@ -8,7 +8,7 @@
#define EVENT_WAKE_TIMER 2
// #define EVENT_RECEIVED_PACKET 3
#define EVENT_PACKET_FOR_PHONE 4
#define EVENT_RECEIVED_TEXT_MSG 5
#define EVENT_RECEIVED_MSG 5
// #define EVENT_BOOT 6 // now done with a timed transition
#define EVENT_BLUETOOTH_PAIR 7
#define EVENT_NODEDB_UPDATED 8 // NodeDB has a big enough change that we think you should turn on the screen
@@ -23,6 +23,6 @@
#define EVENT_INPUT 17 // input broker wants something, we need to wake up and enable screen
extern Fsm powerFSM;
extern State statePOWER, stateSERIAL;
extern State stateON, statePOWER, stateSERIAL, stateDARK;
void PowerFSM_setup();

View File

@@ -1,5 +1,6 @@
#include "OSThread.h"
#include "configuration.h"
#include "memGet.h"
#include <assert.h>
namespace concurrency
@@ -75,12 +76,12 @@ bool OSThread::shouldRun(unsigned long time)
void OSThread::run()
{
#ifdef DEBUG_HEAP
auto heap = ESP.getFreeHeap();
auto heap = memGet.getFreeHeap();
#endif
currentThread = this;
auto newDelay = runOnce();
#ifdef DEBUG_HEAP
auto newHeap = ESP.getFreeHeap();
auto newHeap = memGet.getFreeHeap();
if (newHeap < heap)
LOG_DEBUG("------ Thread %s leaked heap %d -> %d (%d) ------\n", ThreadName.c_str(), heap, newHeap, newHeap - heap);
if (heap < newHeap)

View File

@@ -82,7 +82,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// #define DISABLE_NTP
// Disable the welcome screen and allow
//#define DISABLE_WELCOME_UNSET
// #define DISABLE_WELCOME_UNSET
// -----------------------------------------------------------------------------
// OLED & Input
@@ -93,7 +93,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// The SH1106 controller is almost, but not quite, the same as SSD1306
// Define this if you know you have that controller or your "SSD1306" misbehaves.
//#define USE_SH1106
// #define USE_SH1106
// Define if screen should be mirrored left to right
// #define SCREEN_MIRROR
@@ -118,6 +118,17 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define SHT31_ADDR 0x44
#define PMSA0031_ADDR 0x12
// -----------------------------------------------------------------------------
// ACCELEROMETER
// -----------------------------------------------------------------------------
#define MPU6050_ADDR 0x68
#define LIS3DH_ADR 0x18
// -----------------------------------------------------------------------------
// LED
// -----------------------------------------------------------------------------
#define NCP5623_ADDR 0x38
// -----------------------------------------------------------------------------
// Security
// -----------------------------------------------------------------------------

View File

@@ -34,6 +34,12 @@ ScanI2C::FoundDevice ScanI2C::firstKeyboard() const
return firstOfOrNONE(2, types);
}
ScanI2C::FoundDevice ScanI2C::firstAccelerometer() const
{
ScanI2C::DeviceType types[] = {MPU6050, LIS3DH};
return firstOfOrNONE(2, types);
}
ScanI2C::FoundDevice ScanI2C::find(ScanI2C::DeviceType) const
{
return DEVICE_NONE;

View File

@@ -31,6 +31,9 @@ class ScanI2C
QMI8658,
QMC5883L,
PMSA0031,
MPU6050,
LIS3DH,
NCP5623,
} DeviceType;
// typedef uint8_t DeviceAddress;
@@ -79,6 +82,8 @@ class ScanI2C
FoundDevice firstKeyboard() const;
FoundDevice firstAccelerometer() const;
virtual FoundDevice find(DeviceType) const;
virtual bool exists(DeviceType) const;

View File

@@ -213,6 +213,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port)
break;
SCAN_SIMPLE_CASE(ST7567_ADDRESS, SCREEN_ST7567, "st7567 display found\n")
SCAN_SIMPLE_CASE(NCP5623_ADDR, NCP5623, "NCP5623 RGB LED found\n");
#ifdef HAS_PMU
SCAN_SIMPLE_CASE(XPOWERS_AXP192_AXP2101_ADDRESS, PMU_AXP192_AXP2101, "axp192/axp2101 PMU found\n")
@@ -248,7 +249,17 @@ void ScanI2CTwoWire::scanPort(I2CPort port)
}
break;
SCAN_SIMPLE_CASE(MCP9808_ADDR, MCP9808, "MCP9808 sensor found\n")
case MCP9808_ADDR:
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x07), 2);
if (registerValue == 0x0400) {
type = MCP9808;
LOG_INFO("MCP9808 sensor found\n");
} else {
type = LIS3DH;
LOG_INFO("LIS3DH accelerometer found\n");
}
break;
SCAN_SIMPLE_CASE(SHT31_ADDR, SHT31, "SHT31 sensor found\n")
SCAN_SIMPLE_CASE(SHTC3_ADDR, SHTC3, "SHTC3 sensor found\n")
@@ -261,11 +272,11 @@ void ScanI2CTwoWire::scanPort(I2CPort port)
SCAN_SIMPLE_CASE(QMC5883L_ADDR, QMC5883L, "QMC5883L Highrate 3-Axis magnetic sensor found\n")
SCAN_SIMPLE_CASE(PMSA0031_ADDR, PMSA0031, "PMSA0031 air quality sensor found\n")
SCAN_SIMPLE_CASE(MPU6050_ADDR, MPU6050, "MPU6050 accelerometer found\n");
default:
LOG_INFO("Device found at address 0x%x was not able to be enumerated\n", addr.address);
}
} else if (err == 4) {
LOG_ERROR("Unknown error at address 0x%x\n", addr);
}

View File

@@ -1,5 +1,7 @@
#include "NMEAWPL.h"
#include "GeoCoord.h"
#include "RTC.h"
#include <time.h>
/* -------------------------------------------
* 1 2 3 4 5 6
@@ -56,12 +58,18 @@ uint32_t printWPL(char *buf, size_t bufsz, const meshtastic_Position &pos, const
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 =
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);
tm *t = localtime((time_t *)&pos.timestamp);
if (getRTCQuality() > 0) { // use the device clock if we got time from somewhere. If not, use the GPS timestamp.
uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityDevice);
t = localtime((time_t *)&rtc_sec);
}
uint32_t len = snprintf(
buf, bufsz, "$GNGGA,%02d%02d%02d.%02d,%02d%07.4f,%c,%03d%07.4f,%c,%u,%02u,%04u,%04d,%c,%04d,%c,%d,%04d", t->tm_hour,
t->tm_min, t->tm_sec, pos.timestamp_millis_adjust, 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_quality,
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++) {

View File

@@ -27,6 +27,10 @@
// 1.54 inch 200x200 - GxEPD2_154_M09
//#define TECHO_DISPLAY_MODEL GxEPD2_154_M09
#elif defined(MAKERPYTHON)
// 2.9 inch 296x128 - GxEPD2_290_T5D
#define TECHO_DISPLAY_MODEL GxEPD2_290_T5D
#elif defined(PCA10059)
// 4.2 inch 300x400 - GxEPD2_420_M01
@@ -58,6 +62,9 @@ EInkDisplay::EInkDisplay(uint8_t address, int sda, int scl, OLEDDISPLAY_GEOMETRY
// GxEPD2_154_M09
// setGeometry(GEOMETRY_RAWMODE, 200, 200);
#elif defined(MAKERPYTHON)
// GxEPD2_290_T5D
setGeometry(GEOMETRY_RAWMODE, 296, 128);
#elif defined(PCA10059)
@@ -69,6 +76,11 @@ EInkDisplay::EInkDisplay(uint8_t address, int sda, int scl, OLEDDISPLAY_GEOMETRY
// M5Stack_CoreInk 200x200
// 1.54 inch 200x200 - GxEPD2_154_M09
setGeometry(GEOMETRY_RAWMODE, EPD_HEIGHT, EPD_WIDTH);
#elif defined(my)
// GxEPD2_290_T5D
setGeometry(GEOMETRY_RAWMODE, 296, 128);
LOG_DEBUG("GEOMETRY_RAWMODE, 296, 128\n");
#endif
// setGeometry(GEOMETRY_RAWMODE, 128, 64); // old resolution
@@ -109,7 +121,7 @@ bool EInkDisplay::forceDisplay(uint32_t msecLimit)
#if defined(TTGO_T_ECHO)
// ePaper.Reset(); // wake the screen from sleep
adafruitDisplay->display(false); // FIXME, use partial update mode
#elif defined(RAK4630)
#elif defined(RAK4630) || defined(MAKERPYTHON)
// RAK14000 2.13 inch b/w 250x122 actually now does support partial updates
@@ -125,6 +137,10 @@ bool EInkDisplay::forceDisplay(uint32_t msecLimit)
#elif defined(PCA10059) || defined(M5_COREINK)
adafruitDisplay->nextPage();
#elif defined(PRIVATE_HW) || defined(my)
adafruitDisplay->nextPage();
#endif
// Put screen to sleep to save power (possibly not necessary because we already did poweroff inside of display)
@@ -184,7 +200,7 @@ bool EInkDisplay::connect()
adafruitDisplay->init();
adafruitDisplay->setRotation(3);
}
#elif defined(RAK4630)
#elif defined(RAK4630) || defined(MAKERPYTHON)
{
if (eink_found) {
auto lowLevel = new TECHO_DISPLAY_MODEL(PIN_EINK_CS, PIN_EINK_DC, PIN_EINK_RES, PIN_EINK_BUSY);
@@ -216,6 +232,14 @@ bool EInkDisplay::connect()
adafruitDisplay->init(115200, true, 40, false, SPI, SPISettings(4000000, MSBFIRST, SPI_MODE0));
adafruitDisplay->setRotation(0);
adafruitDisplay->setPartialWindow(0, 0, EPD_WIDTH, EPD_HEIGHT);
#elif defined(my)
{
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, 40, false, SPI, SPISettings(4000000, MSBFIRST, SPI_MODE0));
adafruitDisplay->setRotation(1);
adafruitDisplay->setPartialWindow(0, 0, EPD_WIDTH, EPD_HEIGHT);
}
#endif
// adafruitDisplay->setFullWindow();

View File

@@ -348,8 +348,6 @@ static void drawFrameFirmware(OLEDDisplay *display, OLEDDisplayUiState *state, i
/// Draw the last text message we received
static void drawCriticalFaultFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
displayedNodeNum = 0; // Not currently showing a node pane
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(FONT_MEDIUM);
@@ -370,8 +368,6 @@ static bool shouldDrawMessage(const meshtastic_MeshPacket *packet)
/// Draw the last text message we received
static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
displayedNodeNum = 0; // Not currently showing a node pane
// the max length of this buffer is much longer than we can possibly print
static char tempBuf[237];
@@ -408,6 +404,43 @@ static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state
display->drawStringMaxWidth(0 + x, 0 + y + FONT_HEIGHT_SMALL, x + display->getWidth(), tempBuf);
}
/// Draw the last waypoint we received
static void drawWaypointFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
static char tempBuf[237];
meshtastic_MeshPacket &mp = devicestate.rx_waypoint;
meshtastic_NodeInfo *node = nodeDB.getNode(getFrom(&mp));
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(FONT_SMALL);
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);
}
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);
meshtastic_Waypoint scratch;
memset(&scratch, 0, sizeof(scratch));
if (pb_decode_from_bytes(mp.decoded.payload.bytes, mp.decoded.payload.size, &meshtastic_Waypoint_msg, &scratch)) {
snprintf(tempBuf, sizeof(tempBuf), "Received waypoint: %s", scratch.name);
display->drawStringMaxWidth(0 + x, 0 + y + FONT_HEIGHT_SMALL, x + display->getWidth(), tempBuf);
}
}
/// Draw a series of fields in a column, wrapping to multiple colums if needed
static void drawColumns(OLEDDisplay *display, int16_t x, int16_t y, const char **fields)
{
@@ -773,7 +806,6 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
nodeIndex = (nodeIndex + 1) % nodeDB.getNumNodes();
n = nodeDB.getNodeByIndex(nodeIndex);
}
displayedNodeNum = n->num;
}
meshtastic_NodeInfo *node = nodeDB.getNodeByIndex(nodeIndex);
@@ -1211,7 +1243,7 @@ void Screen::setFrames()
LOG_DEBUG("Total frame count: %d\n", totalFrameCount);
// We don't show the node info our our node (if we have it yet - we should)
size_t numnodes = nodeStatus->getNumTotal();
size_t numnodes = nodeDB.getNumNodes();
if (numnodes > 0)
numnodes--;
@@ -1237,6 +1269,10 @@ void Screen::setFrames()
if (devicestate.has_rx_text_message && shouldDrawMessage(&devicestate.rx_text_message)) {
normalFrames[numframes++] = drawTextMessageFrame;
}
// If we have a waypoint - show it next, unless it's a phone message and we aren't using any special modules
if (devicestate.has_rx_waypoint && shouldDrawMessage(&devicestate.rx_waypoint)) {
normalFrames[numframes++] = drawWaypointFrame;
}
// then all the nodes
// We only show a few nodes in our scrolling list - because meshes with many nodes would have too many screens
@@ -1393,8 +1429,6 @@ void Screen::setFastFramerate()
void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
displayedNodeNum = 0; // Not currently showing a node pane
display->setFont(FONT_SMALL);
// The coordinates define the left starting point of the text
@@ -1502,8 +1536,6 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i
#if HAS_WIFI
const char *wifiName = config.network.wifi_ssid;
displayedNodeNum = 0; // Not currently showing a node pane
display->setFont(FONT_SMALL);
// The coordinates define the left starting point of the text
@@ -1634,8 +1666,6 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i
void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
displayedNodeNum = 0; // Not currently showing a node pane
display->setFont(FONT_SMALL);
// The coordinates define the left starting point of the text

View File

@@ -68,6 +68,10 @@ NRF52Bluetooth *nrf52Bluetooth;
#endif
#include "PowerFSMThread.h"
#if !defined(ARCH_PORTDUINO)
#include "AccelerometerThread.h"
#endif
using namespace concurrency;
// We always create a screen object, but we only init it if we find the hardware
@@ -94,6 +98,10 @@ uint8_t kb_model;
// The I2C address of the RTC Module (if found)
ScanI2C::DeviceAddress rtc_found = ScanI2C::ADDRESS_NONE;
// The I2C address of the Accelerometer (if found)
ScanI2C::DeviceAddress accelerometer_found = ScanI2C::ADDRESS_NONE;
// The I2C address of the RGB LED (if found)
ScanI2C::FoundDevice rgb_found = ScanI2C::FoundDevice(ScanI2C::DeviceType::NONE, ScanI2C::ADDRESS_NONE);
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
ATECCX08A atecc;
@@ -136,17 +144,6 @@ static int32_t ledBlinker()
setLed(ledOn);
#ifdef ARCH_ESP32
auto newHeap = ESP.getFreeHeap();
if (newHeap < 11000) {
LOG_DEBUG("\n\n====== heap too low [11000] -> reboot in 1s ======\n\n");
#ifdef HAS_SCREEN
screen->startRebootScreen();
#endif
rebootAtMsec = millis() + 900;
}
#endif
// have a very sparse duty cycle of LED being on, unless charging, then blink 0.5Hz square wave rate to indicate that
return powerStatus->getIsCharging() ? 1000 : (ledOn ? 1 : 1000);
}
@@ -163,6 +160,7 @@ static OSThread *powerFSMthread;
static OSThread *buttonThread;
uint32_t ButtonThread::longPressTime = 0;
#endif
static OSThread *accelerometerThread;
RadioInterface *rIf = NULL;
@@ -222,10 +220,10 @@ void setup()
// If the button is connected to GPIO 12, don't enable the ability to use
// meshtasticAdmin on the device.
pinMode(BUTTON_PIN, INPUT);
pinMode(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN, INPUT);
#ifdef BUTTON_NEED_PULLUP
gpio_pullup_en((gpio_num_t)BUTTON_PIN);
gpio_pullup_en((gpio_num_t)(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN));
delay(10);
#endif
@@ -238,8 +236,6 @@ void setup()
fsInit();
router = new ReliableRouter();
#ifdef I2C_SDA1
Wire1.begin(I2C_SDA1, I2C_SCL1);
#endif
@@ -350,6 +346,14 @@ void setup()
* nodeTelemetrySensorsMap singleton. This wraps that logic in a temporary scope to declare the temporary field
* "found".
*/
// Only one supported RGB LED currently
rgb_found = i2cScanner->find(ScanI2C::DeviceType::NCP5623);
#if !defined(ARCH_PORTDUINO)
auto acc_info = i2cScanner->firstAccelerometer();
accelerometer_found = acc_info.type != ScanI2C::DeviceType::NONE ? acc_info.address : accelerometer_found;
LOG_DEBUG("acc_info = %i\n", acc_info.type);
#endif
#define STRING(S) #S
@@ -387,10 +391,7 @@ void setup()
// scanEInkDevice();
#endif
#if HAS_BUTTON
// Buttons & LED
buttonThread = new ButtonThread();
#endif
// LED init
#ifdef LED_PIN
pinMode(LED_PIN, OUTPUT);
@@ -414,6 +415,13 @@ void setup()
// If we're taking on the repeater role, use flood router
if (config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER)
router = new FloodingRouter();
else
router = new ReliableRouter();
#if HAS_BUTTON
// Buttons. Moved here cause we need NodeDB to be initialized
buttonThread = new ButtonThread();
#endif
playStartMelody();
@@ -430,6 +438,12 @@ void setup()
screen_model = meshtastic_Config_DisplayConfig_OledType_OLED_SH1107; // keep dimension of 128x64
#endif
#if !defined(ARCH_PORTDUINO)
if (acc_info.type != ScanI2C::DeviceType::NONE) {
accelerometerThread = new AccelerometerThread(acc_info.type);
}
#endif
// Init our SPI controller (must be before screen and lora)
initSPI();
#ifndef ARCH_ESP32
@@ -459,14 +473,14 @@ void setup()
// Now that the mesh service is created, create any modules
setupModules();
// Do this after service.init (because that clears error_code)
// Do this after service.init (because that clears error_code)
#ifdef HAS_PMU
if (!pmu_found)
RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_NO_AXP192); // Record a hardware fault for missing hardware
#endif
// Don't call screen setup until after nodedb is setup (because we need
// the current region name)
// Don't call screen setup until after nodedb is setup (because we need
// the current region name)
#if defined(ST7735_CS) || defined(USE_EINK) || defined(ILI9341_DRIVER)
screen->setup();
#else

View File

@@ -5,6 +5,7 @@
#include "PowerStatus.h"
#include "detect/ScanI2C.h"
#include "graphics/Screen.h"
#include "memGet.h"
#include "mesh/generated/meshtastic/config.pb.h"
#include "mesh/generated/meshtastic/telemetry.pb.h"
#include <map>
@@ -24,6 +25,8 @@ extern ScanI2C::DeviceAddress screen_found;
extern ScanI2C::DeviceAddress cardkb_found;
extern uint8_t kb_model;
extern ScanI2C::DeviceAddress rtc_found;
extern ScanI2C::DeviceAddress accelerometer_found;
extern ScanI2C::FoundDevice rgb_found;
extern bool eink_found;
extern bool pmu_found;

46
src/memGet.cpp Normal file
View File

@@ -0,0 +1,46 @@
#include "memGet.h"
#include "configuration.h"
MemGet memGet;
uint32_t MemGet::getFreeHeap()
{
#ifdef ARCH_ESP32
return ESP.getFreeHeap();
#elif defined(ARCH_NRF52)
return dbgHeapFree();
#else
// this platform does not have heap management function implemented
return UINT32_MAX;
#endif
}
uint32_t MemGet::getHeapSize()
{
#ifdef ARCH_ESP32
return ESP.getHeapSize();
#elif defined(ARCH_NRF52)
return dbgHeapTotal();
#else
// this platform does not have heap management function implemented
return UINT32_MAX;
#endif
}
uint32_t MemGet::getFreePsram()
{
#ifdef ARCH_ESP32
return ESP.getFreePsram();
#else
return 0;
#endif
}
uint32_t MemGet::getPsramSize()
{
#ifdef ARCH_ESP32
return ESP.getPsramSize();
#else
return 0;
#endif
}

18
src/memGet.h Normal file
View File

@@ -0,0 +1,18 @@
#pragma once
#ifndef _MT_MEMGET_H
#define _MT_MEMGET_H
#include <Arduino.h>
class MemGet
{
public:
uint32_t getFreeHeap();
uint32_t getHeapSize();
uint32_t getFreePsram();
uint32_t getPsramSize();
};
extern MemGet memGet;
#endif

View File

@@ -260,6 +260,9 @@ const char *Channels::getName(size_t chIndex)
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST:
channelName = "LongFast";
break;
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE:
channelName = "LongMod";
break;
case meshtastic_Config_LoRaConfig_ModemPreset_VERY_LONG_SLOW:
channelName = "VLongSlow";
break;

View File

@@ -1,6 +1,8 @@
#include "CryptoEngine.h"
#include "configuration.h"
concurrency::Lock *cryptLock;
void CryptoEngine::setKey(const CryptoKey &k)
{
LOG_DEBUG("Using AES%d key!\n", k.length * 8);

View File

@@ -1,7 +1,10 @@
#pragma once
#include "concurrency/LockGuard.h"
#include <Arduino.h>
extern concurrency::Lock *cryptLock;
struct CryptoKey {
uint8_t bytes[32];

View File

@@ -77,8 +77,8 @@ int MeshService::handleFromRadio(const meshtastic_MeshPacket *mp)
nodeDB.updateFrom(*mp); // update our DB state based off sniffing every RX packet from the radio
if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag && !nodeDB.getNode(mp->from)->has_user && nodeInfoModule) {
LOG_INFO("Heard a node we don't know, sending NodeInfo and asking for a response.\n");
nodeInfoModule->sendOurNodeInfo(mp->from, true);
LOG_INFO("Heard a node on channel %d we don't know, sending NodeInfo and asking for a response.\n", mp->channel);
nodeInfoModule->sendOurNodeInfo(mp->from, true, mp->channel);
}
printPacket("Forwarding to phone", mp);
@@ -125,7 +125,6 @@ void MeshService::reloadOwner(bool shouldSave)
// update everyone else and save to disk
if (nodeInfoModule && shouldSave) {
nodeInfoModule->sendOurNodeInfo();
nodeDB.saveToDisk(SEGMENT_DEVICESTATE);
}
}
@@ -242,13 +241,13 @@ void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies)
if (node->has_position && (node->position.latitude_i != 0 || node->position.longitude_i != 0)) {
if (positionModule) {
LOG_INFO("Sending position ping to 0x%x, wantReplies=%d\n", dest, wantReplies);
positionModule->sendOurPosition(dest, wantReplies);
LOG_INFO("Sending position ping to 0x%x, wantReplies=%d, channel=%d\n", dest, wantReplies, node->channel);
positionModule->sendOurPosition(dest, wantReplies, node->channel);
}
} else {
if (nodeInfoModule) {
LOG_INFO("Sending nodeinfo ping to 0x%x, wantReplies=%d\n", dest, wantReplies);
nodeInfoModule->sendOurNodeInfo(dest, wantReplies);
LOG_INFO("Sending nodeinfo ping to 0x%x, wantReplies=%d, channel=%d\n", dest, wantReplies, node->channel);
nodeInfoModule->sendOurNodeInfo(dest, wantReplies, node->channel);
}
}
}

View File

@@ -58,12 +58,6 @@ meshtastic_User &owner = devicestate.owner;
static uint8_t ourMacAddr[6];
/**
* The node number the user is currently looking at
* 0 if none
*/
NodeNum displayedNodeNum;
NodeDB::NodeDB() : nodes(devicestate.node_db), numNodes(&devicestate.node_db_count) {}
/**
@@ -171,6 +165,8 @@ void NodeDB::installDefaultConfig()
config.lora.hop_limit = HOP_RELIABLE;
config.position.gps_enabled = true;
config.position.position_broadcast_smart_enabled = true;
config.position.broadcast_smart_minimum_distance = 100;
config.position.broadcast_smart_minimum_interval_secs = 30;
if (config.device.role != meshtastic_Config_DeviceConfig_Role_ROUTER)
config.device.node_info_broadcast_secs = 3 * 60 * 60;
config.device.serial_enabled = true;
@@ -237,9 +233,7 @@ void NodeDB::installRoleDefaults(meshtastic_Config_DeviceConfig_Role role)
} else if (role == meshtastic_Config_DeviceConfig_Role_REPEATER) {
config.display.screen_on_secs = 1;
} else if (role == meshtastic_Config_DeviceConfig_Role_TRACKER) {
config.position.position_broadcast_smart_enabled = false;
config.position.position_broadcast_secs = 120;
config.position.gps_update_interval = 60;
config.position.gps_update_interval = 30;
} else if (role == meshtastic_Config_DeviceConfig_Role_SENSOR) {
moduleConfig.telemetry.environment_measurement_enabled = true;
moduleConfig.telemetry.environment_update_interval = 300;
@@ -496,6 +490,7 @@ bool NodeDB::saveProto(const char *filename, size_t protoSize, const pb_msgdesc_
} else {
okay = true;
}
f.flush();
f.close();
// brief window of risk here ;-)
@@ -695,11 +690,11 @@ void NodeDB::updateTelemetry(uint32_t nodeId, const meshtastic_Telemetry &t, RxS
/** Update user info for this node based on received user data
*/
void NodeDB::updateUser(uint32_t nodeId, const meshtastic_User &p)
bool NodeDB::updateUser(uint32_t nodeId, const meshtastic_User &p)
{
meshtastic_NodeInfo *info = getOrCreateNode(nodeId);
if (!info) {
return;
return false;
}
LOG_DEBUG("old user %s/%s/%s\n", info->user.id, info->user.long_name, info->user.short_name);
@@ -716,10 +711,11 @@ void NodeDB::updateUser(uint32_t nodeId, const meshtastic_User &p)
powerFSM.trigger(EVENT_NODEDB_UPDATED);
notifyObservers(true); // Force an update whether or not our node counts have changed
// Not really needed - we will save anyways when we go to sleep
// We just changed something important about the user, store our DB
// saveToDisk();
saveToDisk(SEGMENT_DEVICESTATE);
}
return changed;
}
/// given a subpacket sniffed from the network, update our DB state
@@ -727,7 +723,7 @@ void NodeDB::updateUser(uint32_t nodeId, const meshtastic_User &p)
void NodeDB::updateFrom(const meshtastic_MeshPacket &mp)
{
if (mp.which_payload_variant == meshtastic_MeshPacket_decoded_tag && mp.from) {
LOG_DEBUG("Update DB node 0x%x, rx_time=%u\n", mp.from, mp.rx_time);
LOG_DEBUG("Update DB node 0x%x, rx_time=%u, channel=%d\n", mp.from, mp.rx_time, mp.channel);
meshtastic_NodeInfo *info = getOrCreateNode(getFrom(&mp));
if (!info) {
@@ -739,9 +735,22 @@ void NodeDB::updateFrom(const meshtastic_MeshPacket &mp)
if (mp.rx_snr)
info->snr = mp.rx_snr; // keep the most recent SNR we received for this node.
if (mp.decoded.portnum == meshtastic_PortNum_NODEINFO_APP) {
info->channel = mp.channel;
}
}
}
uint8_t NodeDB::getNodeChannel(NodeNum n)
{
meshtastic_NodeInfo *info = getNode(n);
if (!info) {
return 0; // defaults to PRIMARY
}
return info->channel;
}
/// Find a node in our DB, return null for missing
/// NOTE: This function might be called from an ISR
meshtastic_NodeInfo *NodeDB::getNode(NodeNum n)
@@ -759,7 +768,7 @@ meshtastic_NodeInfo *NodeDB::getOrCreateNode(NodeNum n)
meshtastic_NodeInfo *info = getNode(n);
if (!info) {
if (*numNodes >= MAX_NUM_NODES) {
if ((*numNodes >= MAX_NUM_NODES) || (memGet.getFreeHeap() < meshtastic_NodeInfo_size * 3)) {
screen->print("warning: node_db full! erasing oldest entry\n");
// look for oldest node and erase it
uint32_t oldest = UINT32_MAX;

View File

@@ -86,7 +86,7 @@ class NodeDB
/** Update user info for this node based on received user data
*/
void updateUser(uint32_t nodeId, const meshtastic_User &p);
bool updateUser(uint32_t nodeId, const meshtastic_User &p);
/// @return our node number
NodeNum getNodeNum() { return myNodeInfo.my_node_num; }
@@ -113,6 +113,9 @@ class NodeDB
/// pick a provisional nodenum we hope no one is using
void pickNewNodeNum();
// get channel channel index we heard a nodeNum on, defaults to 0 if not found
uint8_t getNodeChannel(NodeNum n);
/// Find a node in our DB, return null for missing
meshtastic_NodeInfo *getNode(NodeNum n);
@@ -153,12 +156,6 @@ class NodeDB
void installDefaultDeviceState(), installDefaultChannels(), installDefaultConfig(), installDefaultModuleConfig();
};
/**
* The node number the user is currently looking at
* 0 if none
*/
extern NodeNum displayedNodeNum;
extern NodeDB nodeDB;
/*

View File

@@ -15,7 +15,7 @@ RF95Interface::RF95Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOL
SPIClass &spi)
: RadioLibInterface(cs, irq, rst, busy, spi)
{
// FIXME - we assume devices never get destroyed
LOG_WARN("RF95Interface(cs=%d, irq=%d, rst=%d, busy=%d)\n", cs, irq, rst, busy);
}
/** Some boards require GPIO control of tx vs rx paths */

View File

@@ -281,8 +281,8 @@ void printPacket(const char *prefix, const meshtastic_MeshPacket *p)
if (p->priority != 0)
out += DEBUG_PORT.mt_sprintf(" priority=%d", p->priority);
out += ")\n";
LOG_DEBUG("%s", out.c_str());
out += ")";
LOG_DEBUG("%s\n", out.c_str());
}
RadioInterface::RadioInterface()

View File

@@ -55,6 +55,10 @@ Router::Router() : concurrency::OSThread("Router"), fromRadioQueue(MAX_RX_FROMRA
LOG_DEBUG("Size of MeshPacket %d\n", sizeof(MeshPacket)); */
fromRadioQueue.setReader(this);
// init Lockguard for crypt operations
assert(!cryptLock);
cryptLock = new concurrency::Lock();
}
/**
@@ -173,6 +177,11 @@ ErrorCode Router::sendLocal(meshtastic_MeshPacket *p, RxSource src)
handleReceived(p, src);
}
if (!p->channel) { // don't override if a channel was requested
p->channel = nodeDB.getNodeChannel(p->to);
LOG_DEBUG("localSend to channel %d\n", p->channel);
}
return send(p);
}
}
@@ -300,6 +309,8 @@ void Router::sniffReceived(const meshtastic_MeshPacket *p, const meshtastic_Rout
bool perhapsDecode(meshtastic_MeshPacket *p)
{
concurrency::LockGuard g(cryptLock);
if (config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER &&
config.device.rebroadcast_mode == meshtastic_Config_DeviceConfig_RebroadcastMode_ALL_SKIP_DECODING)
return false;
@@ -366,6 +377,8 @@ bool perhapsDecode(meshtastic_MeshPacket *p)
*/
meshtastic_Routing_Error perhapsEncode(meshtastic_MeshPacket *p)
{
concurrency::LockGuard g(cryptLock);
// If the packet is not yet encrypted, do so now
if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
size_t numbytes = pb_encode_to_bytes(bytes, sizeof(bytes), &meshtastic_Data_msg, &p->decoded);

View File

@@ -13,6 +13,7 @@ SX128xInterface<T>::SX128xInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq,
SPIClass &spi)
: RadioLibInterface(cs, irq, rst, busy, spi, &lora), lora(&module)
{
LOG_WARN("SX128xInterface(cs=%d, irq=%d, rst=%d, busy=%d)\n", cs, irq, rst, busy);
}
/// Initialise the Driver transport hardware and software.
@@ -73,6 +74,12 @@ template <typename T> bool SX128xInterface<T>::init()
LOG_INFO("Bandwidth set to %f\n", bw);
LOG_INFO("Power output set to %d\n", power);
#if defined(SX128X_TXEN) && (SX128X_TXEN != RADIOLIB_NC) && defined(SX128X_RXEN) && (SX128X_RXEN != RADIOLIB_NC)
if (res == RADIOLIB_ERR_NONE) {
lora.setRfSwitchPins(SX128X_RXEN, SX128X_TXEN);
}
#endif
if (res == RADIOLIB_ERR_NONE)
res = lora.setCRC(2);

View File

@@ -31,11 +31,9 @@ typedef enum _meshtastic_Channel_Role {
/* Struct definitions */
typedef PB_BYTES_ARRAY_T(32) meshtastic_ChannelSettings_psk_t;
/* Full settings (center freq, spread factor, pre-shared secret key etc...)
needed to configure a radio for speaking on a particular channel This
information can be encoded as a QRcode/url so that other users can configure
/* This information can be encoded as a QRcode/url so that other users can configure
their radio to join the same channel.
A note about how channel names are shown to users: channelname-Xy
A note about how channel names are shown to users: channelname-X
poundsymbol is a prefix used to indicate this is a channel name (idea from @professr).
Where X is a letter from A-Z (base 26) representing a hash of the PSK for this
channel - so that if the user changes anything about the channel (which does
@@ -45,8 +43,6 @@ typedef PB_BYTES_ARRAY_T(32) meshtastic_ChannelSettings_psk_t;
The PSK is hashed into this letter by "0x41 + [xor all bytes of the psk ] modulo 26"
This also allows the option of someday if people have the PSK off (zero), the
users COULD type in a channel name and be able to talk.
Y is a lower case letter from a-z that represents the channel 'speed' settings
(for some future definition of speed)
FIXME: Add description of multi-channel support and how primary vs secondary channels are used.
FIXME: explain how apps use channels for security.
explain how remote settings and remote gpio are managed as an example */
@@ -60,7 +56,7 @@ typedef struct _meshtastic_ChannelSettings {
because they are listed in this source code.
Those bytes are mapped using the following scheme:
`0` = No crypto
`1` = The special "default" channel key: {0xd4, 0xf1, 0xbb, 0x3a, 0x20, 0x29, 0x07, 0x59, 0xf0, 0xbc, 0xff, 0xab, 0xcf, 0x4e, 0x69, 0xbf}
`1` = The special "default" channel key: {0xd4, 0xf1, 0xbb, 0x3a, 0x20, 0x29, 0x07, 0x59, 0xf0, 0xbc, 0xff, 0xab, 0xcf, 0x4e, 0x69, 0x01}
`2` through 10 = The default channel key, except with 1 through 9 added to the last byte.
Shown to user as simple1 through 10 */
meshtastic_ChannelSettings_psk_t psk;

View File

@@ -0,0 +1,12 @@
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.4.7 */
#include "meshtastic/clientonly.pb.h"
#if PB_PROTO_HEADER_VERSION != 40
#error Regenerate this file with the current version of nanopb generator.
#endif
PB_BIND(meshtastic_DeviceProfile, meshtastic_DeviceProfile, 2)

View File

@@ -0,0 +1,73 @@
/* Automatically generated nanopb header */
/* Generated by nanopb-0.4.7 */
#ifndef PB_MESHTASTIC_MESHTASTIC_CLIENTONLY_PB_H_INCLUDED
#define PB_MESHTASTIC_MESHTASTIC_CLIENTONLY_PB_H_INCLUDED
#include <pb.h>
#include "meshtastic/localonly.pb.h"
#if PB_PROTO_HEADER_VERSION != 40
#error Regenerate this file with the current version of nanopb generator.
#endif
/* Struct definitions */
/* This abstraction is used to contain any configuration for provisioning a node on any client.
It is useful for importing and exporting configurations. */
typedef struct _meshtastic_DeviceProfile {
/* Long name for the node */
bool has_long_name;
char long_name[40];
/* Short name of the node */
bool has_short_name;
char short_name[5];
/* The url of the channels from our node */
pb_callback_t channel_url;
/* The Config of the node */
bool has_config;
meshtastic_LocalConfig config;
/* The ModuleConfig of the node */
bool has_module_config;
meshtastic_LocalModuleConfig module_config;
} meshtastic_DeviceProfile;
#ifdef __cplusplus
extern "C" {
#endif
/* Initializer values for message structs */
#define meshtastic_DeviceProfile_init_default {false, "", false, "", {{NULL}, NULL}, false, meshtastic_LocalConfig_init_default, false, meshtastic_LocalModuleConfig_init_default}
#define meshtastic_DeviceProfile_init_zero {false, "", false, "", {{NULL}, NULL}, false, meshtastic_LocalConfig_init_zero, false, meshtastic_LocalModuleConfig_init_zero}
/* Field tags (for use in manual encoding/decoding) */
#define meshtastic_DeviceProfile_long_name_tag 1
#define meshtastic_DeviceProfile_short_name_tag 2
#define meshtastic_DeviceProfile_channel_url_tag 3
#define meshtastic_DeviceProfile_config_tag 4
#define meshtastic_DeviceProfile_module_config_tag 5
/* Struct field encoding specification for nanopb */
#define meshtastic_DeviceProfile_FIELDLIST(X, a) \
X(a, STATIC, OPTIONAL, STRING, long_name, 1) \
X(a, STATIC, OPTIONAL, STRING, short_name, 2) \
X(a, CALLBACK, OPTIONAL, STRING, channel_url, 3) \
X(a, STATIC, OPTIONAL, MESSAGE, config, 4) \
X(a, STATIC, OPTIONAL, MESSAGE, module_config, 5)
#define meshtastic_DeviceProfile_CALLBACK pb_default_field_callback
#define meshtastic_DeviceProfile_DEFAULT NULL
#define meshtastic_DeviceProfile_config_MSGTYPE meshtastic_LocalConfig
#define meshtastic_DeviceProfile_module_config_MSGTYPE meshtastic_LocalModuleConfig
extern const pb_msgdesc_t meshtastic_DeviceProfile_msg;
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
#define meshtastic_DeviceProfile_fields &meshtastic_DeviceProfile_msg
/* Maximum encoded size of messages (where known) */
/* meshtastic_DeviceProfile_size depends on runtime parameters */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif

View File

@@ -231,6 +231,8 @@ typedef struct _meshtastic_Config_DeviceConfig {
/* Send our nodeinfo this often
Defaults to 900 Seconds (15 minutes) */
uint32_t node_info_broadcast_secs;
/* Treat double tap interrupt on supported accelerometers as a button press if set to true */
bool double_tap_as_button_press;
} meshtastic_Config_DeviceConfig;
/* Position Config */
@@ -262,6 +264,10 @@ typedef struct _meshtastic_Config_PositionConfig {
uint32_t rx_gpio;
/* (Re)define GPS_TX_PIN for your board. */
uint32_t tx_gpio;
/* The minimum distance in meters traveled (since the last send) before we can send a position to the mesh if position_broadcast_smart_enabled */
uint32_t broadcast_smart_minimum_distance;
/* The minumum number of seconds (since the last send) before we can send a position to the mesh if position_broadcast_smart_enabled */
uint32_t broadcast_smart_minimum_interval_secs;
} meshtastic_Config_PositionConfig;
/* Power Config\
@@ -360,6 +366,8 @@ typedef struct _meshtastic_Config_DisplayConfig {
meshtastic_Config_DisplayConfig_DisplayMode displaymode;
/* Print first line in pseudo-bold? FALSE is original style, TRUE is bold */
bool heading_bold;
/* Should we wake the screen up on accelerometer detected motion or tap */
bool wake_on_tap_or_motion;
} meshtastic_Config_DisplayConfig;
/* Lora Config */
@@ -521,21 +529,21 @@ extern "C" {
/* Initializer values for message structs */
#define meshtastic_Config_init_default {0, {meshtastic_Config_DeviceConfig_init_default}}
#define meshtastic_Config_DeviceConfig_init_default {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0}
#define meshtastic_Config_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_Config_DeviceConfig_init_default {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0}
#define meshtastic_Config_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_Config_PowerConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_Config_NetworkConfig_init_default {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_default, ""}
#define meshtastic_Config_NetworkConfig_IpV4Config_init_default {0, 0, 0, 0}
#define meshtastic_Config_DisplayConfig_init_default {0, _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0}
#define meshtastic_Config_DisplayConfig_init_default {0, _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0, 0}
#define meshtastic_Config_LoRaConfig_init_default {0, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _meshtastic_Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}}
#define meshtastic_Config_BluetoothConfig_init_default {0, _meshtastic_Config_BluetoothConfig_PairingMode_MIN, 0}
#define meshtastic_Config_init_zero {0, {meshtastic_Config_DeviceConfig_init_zero}}
#define meshtastic_Config_DeviceConfig_init_zero {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0}
#define meshtastic_Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_Config_DeviceConfig_init_zero {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0}
#define meshtastic_Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_Config_PowerConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_Config_NetworkConfig_init_zero {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_zero, ""}
#define meshtastic_Config_NetworkConfig_IpV4Config_init_zero {0, 0, 0, 0}
#define meshtastic_Config_DisplayConfig_init_zero {0, _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0}
#define meshtastic_Config_DisplayConfig_init_zero {0, _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0, 0}
#define meshtastic_Config_LoRaConfig_init_zero {0, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _meshtastic_Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}}
#define meshtastic_Config_BluetoothConfig_init_zero {0, _meshtastic_Config_BluetoothConfig_PairingMode_MIN, 0}
@@ -547,6 +555,7 @@ extern "C" {
#define meshtastic_Config_DeviceConfig_buzzer_gpio_tag 5
#define meshtastic_Config_DeviceConfig_rebroadcast_mode_tag 6
#define meshtastic_Config_DeviceConfig_node_info_broadcast_secs_tag 7
#define meshtastic_Config_DeviceConfig_double_tap_as_button_press_tag 8
#define meshtastic_Config_PositionConfig_position_broadcast_secs_tag 1
#define meshtastic_Config_PositionConfig_position_broadcast_smart_enabled_tag 2
#define meshtastic_Config_PositionConfig_fixed_position_tag 3
@@ -556,6 +565,8 @@ extern "C" {
#define meshtastic_Config_PositionConfig_position_flags_tag 7
#define meshtastic_Config_PositionConfig_rx_gpio_tag 8
#define meshtastic_Config_PositionConfig_tx_gpio_tag 9
#define meshtastic_Config_PositionConfig_broadcast_smart_minimum_distance_tag 10
#define meshtastic_Config_PositionConfig_broadcast_smart_minimum_interval_secs_tag 11
#define meshtastic_Config_PowerConfig_is_power_saving_tag 1
#define meshtastic_Config_PowerConfig_on_battery_shutdown_after_secs_tag 2
#define meshtastic_Config_PowerConfig_adc_multiplier_override_tag 3
@@ -585,6 +596,7 @@ extern "C" {
#define meshtastic_Config_DisplayConfig_oled_tag 7
#define meshtastic_Config_DisplayConfig_displaymode_tag 8
#define meshtastic_Config_DisplayConfig_heading_bold_tag 9
#define meshtastic_Config_DisplayConfig_wake_on_tap_or_motion_tag 10
#define meshtastic_Config_LoRaConfig_use_preset_tag 1
#define meshtastic_Config_LoRaConfig_modem_preset_tag 2
#define meshtastic_Config_LoRaConfig_bandwidth_tag 3
@@ -637,7 +649,8 @@ X(a, STATIC, SINGULAR, BOOL, debug_log_enabled, 3) \
X(a, STATIC, SINGULAR, UINT32, button_gpio, 4) \
X(a, STATIC, SINGULAR, UINT32, buzzer_gpio, 5) \
X(a, STATIC, SINGULAR, UENUM, rebroadcast_mode, 6) \
X(a, STATIC, SINGULAR, UINT32, node_info_broadcast_secs, 7)
X(a, STATIC, SINGULAR, UINT32, node_info_broadcast_secs, 7) \
X(a, STATIC, SINGULAR, BOOL, double_tap_as_button_press, 8)
#define meshtastic_Config_DeviceConfig_CALLBACK NULL
#define meshtastic_Config_DeviceConfig_DEFAULT NULL
@@ -650,7 +663,9 @@ X(a, STATIC, SINGULAR, UINT32, gps_update_interval, 5) \
X(a, STATIC, SINGULAR, UINT32, gps_attempt_time, 6) \
X(a, STATIC, SINGULAR, UINT32, position_flags, 7) \
X(a, STATIC, SINGULAR, UINT32, rx_gpio, 8) \
X(a, STATIC, SINGULAR, UINT32, tx_gpio, 9)
X(a, STATIC, SINGULAR, UINT32, tx_gpio, 9) \
X(a, STATIC, SINGULAR, UINT32, broadcast_smart_minimum_distance, 10) \
X(a, STATIC, SINGULAR, UINT32, broadcast_smart_minimum_interval_secs, 11)
#define meshtastic_Config_PositionConfig_CALLBACK NULL
#define meshtastic_Config_PositionConfig_DEFAULT NULL
@@ -696,7 +711,8 @@ X(a, STATIC, SINGULAR, BOOL, flip_screen, 5) \
X(a, STATIC, SINGULAR, UENUM, units, 6) \
X(a, STATIC, SINGULAR, UENUM, oled, 7) \
X(a, STATIC, SINGULAR, UENUM, displaymode, 8) \
X(a, STATIC, SINGULAR, BOOL, heading_bold, 9)
X(a, STATIC, SINGULAR, BOOL, heading_bold, 9) \
X(a, STATIC, SINGULAR, BOOL, wake_on_tap_or_motion, 10)
#define meshtastic_Config_DisplayConfig_CALLBACK NULL
#define meshtastic_Config_DisplayConfig_DEFAULT NULL
@@ -749,12 +765,12 @@ extern const pb_msgdesc_t meshtastic_Config_BluetoothConfig_msg;
/* Maximum encoded size of messages (where known) */
#define meshtastic_Config_BluetoothConfig_size 10
#define meshtastic_Config_DeviceConfig_size 26
#define meshtastic_Config_DisplayConfig_size 26
#define meshtastic_Config_DeviceConfig_size 28
#define meshtastic_Config_DisplayConfig_size 28
#define meshtastic_Config_LoRaConfig_size 77
#define meshtastic_Config_NetworkConfig_IpV4Config_size 20
#define meshtastic_Config_NetworkConfig_size 195
#define meshtastic_Config_PositionConfig_size 42
#define meshtastic_Config_PositionConfig_size 54
#define meshtastic_Config_PowerConfig_size 43
#define meshtastic_Config_size 198

View File

@@ -56,6 +56,11 @@ typedef struct _meshtastic_DeviceState {
bool no_save;
/* Some GPS receivers seem to have bogus settings from the factory, so we always do one factory reset. */
bool did_gps_reset;
/* We keep the last received waypoint stored in the device flash,
so we can show it on the screen.
Might be null */
bool has_rx_waypoint;
meshtastic_MeshPacket rx_waypoint;
} meshtastic_DeviceState;
/* The on-disk saved channels */
@@ -110,10 +115,10 @@ extern "C" {
/* Initializer values for message structs */
#define meshtastic_DeviceState_init_default {false, meshtastic_MyNodeInfo_init_default, false, meshtastic_User_init_default, 0, {meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default}, 0, {meshtastic_MeshPacket_init_default}, false, meshtastic_MeshPacket_init_default, 0, 0, 0}
#define meshtastic_DeviceState_init_default {false, meshtastic_MyNodeInfo_init_default, false, meshtastic_User_init_default, 0, {meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default}, 0, {meshtastic_MeshPacket_init_default}, false, meshtastic_MeshPacket_init_default, 0, 0, 0, false, meshtastic_MeshPacket_init_default}
#define meshtastic_ChannelFile_init_default {0, {meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default}, 0}
#define meshtastic_OEMStore_init_default {0, 0, {0, {0}}, _meshtastic_ScreenFonts_MIN, "", {0, {0}}, false, meshtastic_LocalConfig_init_default, false, meshtastic_LocalModuleConfig_init_default}
#define meshtastic_DeviceState_init_zero {false, meshtastic_MyNodeInfo_init_zero, false, meshtastic_User_init_zero, 0, {meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero}, 0, {meshtastic_MeshPacket_init_zero}, false, meshtastic_MeshPacket_init_zero, 0, 0, 0}
#define meshtastic_DeviceState_init_zero {false, meshtastic_MyNodeInfo_init_zero, false, meshtastic_User_init_zero, 0, {meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero}, 0, {meshtastic_MeshPacket_init_zero}, false, meshtastic_MeshPacket_init_zero, 0, 0, 0, false, meshtastic_MeshPacket_init_zero}
#define meshtastic_ChannelFile_init_zero {0, {meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero}, 0}
#define meshtastic_OEMStore_init_zero {0, 0, {0, {0}}, _meshtastic_ScreenFonts_MIN, "", {0, {0}}, false, meshtastic_LocalConfig_init_zero, false, meshtastic_LocalModuleConfig_init_zero}
@@ -126,6 +131,7 @@ extern "C" {
#define meshtastic_DeviceState_version_tag 8
#define meshtastic_DeviceState_no_save_tag 9
#define meshtastic_DeviceState_did_gps_reset_tag 11
#define meshtastic_DeviceState_rx_waypoint_tag 12
#define meshtastic_ChannelFile_channels_tag 1
#define meshtastic_ChannelFile_version_tag 2
#define meshtastic_OEMStore_oem_icon_width_tag 1
@@ -146,7 +152,8 @@ X(a, STATIC, REPEATED, MESSAGE, receive_queue, 5) \
X(a, STATIC, OPTIONAL, MESSAGE, rx_text_message, 7) \
X(a, STATIC, SINGULAR, UINT32, version, 8) \
X(a, STATIC, SINGULAR, BOOL, no_save, 9) \
X(a, STATIC, SINGULAR, BOOL, did_gps_reset, 11)
X(a, STATIC, SINGULAR, BOOL, did_gps_reset, 11) \
X(a, STATIC, OPTIONAL, MESSAGE, rx_waypoint, 12)
#define meshtastic_DeviceState_CALLBACK NULL
#define meshtastic_DeviceState_DEFAULT NULL
#define meshtastic_DeviceState_my_node_MSGTYPE meshtastic_MyNodeInfo
@@ -154,6 +161,7 @@ X(a, STATIC, SINGULAR, BOOL, did_gps_reset, 11)
#define meshtastic_DeviceState_node_db_MSGTYPE meshtastic_NodeInfo
#define meshtastic_DeviceState_receive_queue_MSGTYPE meshtastic_MeshPacket
#define meshtastic_DeviceState_rx_text_message_MSGTYPE meshtastic_MeshPacket
#define meshtastic_DeviceState_rx_waypoint_MSGTYPE meshtastic_MeshPacket
#define meshtastic_ChannelFile_FIELDLIST(X, a) \
X(a, STATIC, REPEATED, MESSAGE, channels, 1) \
@@ -187,8 +195,8 @@ extern const pb_msgdesc_t meshtastic_OEMStore_msg;
/* Maximum encoded size of messages (where known) */
#define meshtastic_ChannelFile_size 638
#define meshtastic_DeviceState_size 21800
#define meshtastic_OEMStore_size 3006
#define meshtastic_DeviceState_size 22364
#define meshtastic_OEMStore_size 3041
#ifdef __cplusplus
} /* extern "C" */

View File

@@ -156,8 +156,8 @@ extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg;
#define meshtastic_LocalModuleConfig_fields &meshtastic_LocalModuleConfig_msg
/* Maximum encoded size of messages (where known) */
#define meshtastic_LocalConfig_size 440
#define meshtastic_LocalModuleConfig_size 420
#define meshtastic_LocalConfig_size 456
#define meshtastic_LocalModuleConfig_size 439
#ifdef __cplusplus
} /* extern "C" */

View File

@@ -48,6 +48,12 @@ PB_BIND(meshtastic_ToRadio, meshtastic_ToRadio, 2)
PB_BIND(meshtastic_Compressed, meshtastic_Compressed, AUTO)
PB_BIND(meshtastic_NeighborInfo, meshtastic_NeighborInfo, AUTO)
PB_BIND(meshtastic_Neighbor, meshtastic_Neighbor, AUTO)
PB_BIND(meshtastic_DeviceMetadata, meshtastic_DeviceMetadata, AUTO)

View File

@@ -563,6 +563,8 @@ typedef struct _meshtastic_NodeInfo {
/* The latest device metrics for the node. */
bool has_device_metrics;
meshtastic_DeviceMetrics device_metrics;
/* local channel index we heard that node on. Only populated if its not the default channel. */
uint8_t channel;
} meshtastic_NodeInfo;
/* Unique local debugging info for this node
@@ -678,6 +680,25 @@ typedef struct _meshtastic_Compressed {
meshtastic_Compressed_data_t data;
} meshtastic_Compressed;
/* A single edge in the mesh */
typedef struct _meshtastic_Neighbor {
/* Node ID of neighbor */
uint32_t node_id;
/* SNR of last heard message */
float snr;
} meshtastic_Neighbor;
/* Full info on edges for a single node */
typedef struct _meshtastic_NeighborInfo {
/* The node ID of the node sending info on its neighbors */
uint32_t node_id;
/* Field to pass neighbor info for the next sending cycle */
uint32_t last_sent_by_id;
/* The list of out edges from this node */
pb_size_t neighbors_count;
meshtastic_Neighbor neighbors[10];
} meshtastic_NeighborInfo;
/* Device metadata response */
typedef struct _meshtastic_DeviceMetadata {
/* Device firmware version string */
@@ -811,6 +832,8 @@ extern "C" {
#define meshtastic_Compressed_portnum_ENUMTYPE meshtastic_PortNum
#define meshtastic_DeviceMetadata_role_ENUMTYPE meshtastic_Config_DeviceConfig_Role
#define meshtastic_DeviceMetadata_hw_model_ENUMTYPE meshtastic_HardwareModel
@@ -823,13 +846,15 @@ extern "C" {
#define meshtastic_Data_init_default {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0}
#define meshtastic_Waypoint_init_default {0, 0, 0, 0, 0, "", "", 0}
#define meshtastic_MeshPacket_init_default {0, 0, 0, 0, {meshtastic_Data_init_default}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN}
#define meshtastic_NodeInfo_init_default {0, false, meshtastic_User_init_default, false, meshtastic_Position_init_default, 0, 0, false, meshtastic_DeviceMetrics_init_default}
#define meshtastic_NodeInfo_init_default {0, false, meshtastic_User_init_default, false, meshtastic_Position_init_default, 0, 0, false, meshtastic_DeviceMetrics_init_default, 0}
#define meshtastic_MyNodeInfo_init_default {0, 0, 0, "", _meshtastic_CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0}
#define meshtastic_LogRecord_init_default {"", 0, "", _meshtastic_LogRecord_Level_MIN}
#define meshtastic_QueueStatus_init_default {0, 0, 0, 0}
#define meshtastic_FromRadio_init_default {0, 0, {meshtastic_MeshPacket_init_default}}
#define meshtastic_ToRadio_init_default {0, {meshtastic_MeshPacket_init_default}}
#define meshtastic_Compressed_init_default {_meshtastic_PortNum_MIN, {0, {0}}}
#define meshtastic_NeighborInfo_init_default {0, 0, 0, {meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default}}
#define meshtastic_Neighbor_init_default {0, 0}
#define meshtastic_DeviceMetadata_init_default {"", 0, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_Role_MIN, 0, _meshtastic_HardwareModel_MIN}
#define meshtastic_Position_init_zero {0, 0, 0, 0, _meshtastic_Position_LocSource_MIN, _meshtastic_Position_AltSource_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_User_init_zero {"", "", "", {0}, _meshtastic_HardwareModel_MIN, 0}
@@ -838,13 +863,15 @@ extern "C" {
#define meshtastic_Data_init_zero {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0}
#define meshtastic_Waypoint_init_zero {0, 0, 0, 0, 0, "", "", 0}
#define meshtastic_MeshPacket_init_zero {0, 0, 0, 0, {meshtastic_Data_init_zero}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN}
#define meshtastic_NodeInfo_init_zero {0, false, meshtastic_User_init_zero, false, meshtastic_Position_init_zero, 0, 0, false, meshtastic_DeviceMetrics_init_zero}
#define meshtastic_NodeInfo_init_zero {0, false, meshtastic_User_init_zero, false, meshtastic_Position_init_zero, 0, 0, false, meshtastic_DeviceMetrics_init_zero, 0}
#define meshtastic_MyNodeInfo_init_zero {0, 0, 0, "", _meshtastic_CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0}
#define meshtastic_LogRecord_init_zero {"", 0, "", _meshtastic_LogRecord_Level_MIN}
#define meshtastic_QueueStatus_init_zero {0, 0, 0, 0}
#define meshtastic_FromRadio_init_zero {0, 0, {meshtastic_MeshPacket_init_zero}}
#define meshtastic_ToRadio_init_zero {0, {meshtastic_MeshPacket_init_zero}}
#define meshtastic_Compressed_init_zero {_meshtastic_PortNum_MIN, {0, {0}}}
#define meshtastic_NeighborInfo_init_zero {0, 0, 0, {meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero}}
#define meshtastic_Neighbor_init_zero {0, 0}
#define meshtastic_DeviceMetadata_init_zero {"", 0, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_Role_MIN, 0, _meshtastic_HardwareModel_MIN}
/* Field tags (for use in manual encoding/decoding) */
@@ -915,6 +942,7 @@ extern "C" {
#define meshtastic_NodeInfo_snr_tag 4
#define meshtastic_NodeInfo_last_heard_tag 5
#define meshtastic_NodeInfo_device_metrics_tag 6
#define meshtastic_NodeInfo_channel_tag 7
#define meshtastic_MyNodeInfo_my_node_num_tag 1
#define meshtastic_MyNodeInfo_has_gps_tag 2
#define meshtastic_MyNodeInfo_max_channels_tag 3
@@ -945,6 +973,11 @@ extern "C" {
#define meshtastic_ToRadio_xmodemPacket_tag 5
#define meshtastic_Compressed_portnum_tag 1
#define meshtastic_Compressed_data_tag 2
#define meshtastic_Neighbor_node_id_tag 1
#define meshtastic_Neighbor_snr_tag 2
#define meshtastic_NeighborInfo_node_id_tag 1
#define meshtastic_NeighborInfo_last_sent_by_id_tag 2
#define meshtastic_NeighborInfo_neighbors_tag 3
#define meshtastic_DeviceMetadata_firmware_version_tag 1
#define meshtastic_DeviceMetadata_device_state_version_tag 2
#define meshtastic_DeviceMetadata_canShutdown_tag 3
@@ -1067,7 +1100,8 @@ X(a, STATIC, OPTIONAL, MESSAGE, user, 2) \
X(a, STATIC, OPTIONAL, MESSAGE, position, 3) \
X(a, STATIC, SINGULAR, FLOAT, snr, 4) \
X(a, STATIC, SINGULAR, FIXED32, last_heard, 5) \
X(a, STATIC, OPTIONAL, MESSAGE, device_metrics, 6)
X(a, STATIC, OPTIONAL, MESSAGE, device_metrics, 6) \
X(a, STATIC, SINGULAR, UINT32, channel, 7)
#define meshtastic_NodeInfo_CALLBACK NULL
#define meshtastic_NodeInfo_DEFAULT NULL
#define meshtastic_NodeInfo_user_MSGTYPE meshtastic_User
@@ -1153,6 +1187,20 @@ X(a, STATIC, SINGULAR, BYTES, data, 2)
#define meshtastic_Compressed_CALLBACK NULL
#define meshtastic_Compressed_DEFAULT NULL
#define meshtastic_NeighborInfo_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, UINT32, node_id, 1) \
X(a, STATIC, SINGULAR, UINT32, last_sent_by_id, 2) \
X(a, STATIC, REPEATED, MESSAGE, neighbors, 3)
#define meshtastic_NeighborInfo_CALLBACK NULL
#define meshtastic_NeighborInfo_DEFAULT NULL
#define meshtastic_NeighborInfo_neighbors_MSGTYPE meshtastic_Neighbor
#define meshtastic_Neighbor_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, UINT32, node_id, 1) \
X(a, STATIC, SINGULAR, FLOAT, snr, 2)
#define meshtastic_Neighbor_CALLBACK NULL
#define meshtastic_Neighbor_DEFAULT NULL
#define meshtastic_DeviceMetadata_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, STRING, firmware_version, 1) \
X(a, STATIC, SINGULAR, UINT32, device_state_version, 2) \
@@ -1180,6 +1228,8 @@ extern const pb_msgdesc_t meshtastic_QueueStatus_msg;
extern const pb_msgdesc_t meshtastic_FromRadio_msg;
extern const pb_msgdesc_t meshtastic_ToRadio_msg;
extern const pb_msgdesc_t meshtastic_Compressed_msg;
extern const pb_msgdesc_t meshtastic_NeighborInfo_msg;
extern const pb_msgdesc_t meshtastic_Neighbor_msg;
extern const pb_msgdesc_t meshtastic_DeviceMetadata_msg;
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
@@ -1197,6 +1247,8 @@ extern const pb_msgdesc_t meshtastic_DeviceMetadata_msg;
#define meshtastic_FromRadio_fields &meshtastic_FromRadio_msg
#define meshtastic_ToRadio_fields &meshtastic_ToRadio_msg
#define meshtastic_Compressed_fields &meshtastic_Compressed_msg
#define meshtastic_NeighborInfo_fields &meshtastic_NeighborInfo_msg
#define meshtastic_Neighbor_fields &meshtastic_Neighbor_msg
#define meshtastic_DeviceMetadata_fields &meshtastic_DeviceMetadata_msg
/* Maximum encoded size of messages (where known) */
@@ -1207,7 +1259,9 @@ extern const pb_msgdesc_t meshtastic_DeviceMetadata_msg;
#define meshtastic_LogRecord_size 81
#define meshtastic_MeshPacket_size 321
#define meshtastic_MyNodeInfo_size 179
#define meshtastic_NodeInfo_size 258
#define meshtastic_NeighborInfo_size 142
#define meshtastic_Neighbor_size 11
#define meshtastic_NodeInfo_size 261
#define meshtastic_Position_size 137
#define meshtastic_QueueStatus_size 23
#define meshtastic_RouteDiscovery_size 40

View File

@@ -96,6 +96,11 @@ typedef struct _meshtastic_ModuleConfig_MQTTConfig {
bool encryption_enabled;
/* Whether to send / consume json packets on MQTT */
bool json_enabled;
/* If true, we attempt to establish a secure connection using TLS */
bool tls_enabled;
/* The root topic to use for MQTT messages. Default is "msh".
This is useful if you want to use a single MQTT server for multiple meshtastic networks and separate them via ACLs */
char root[16];
} meshtastic_ModuleConfig_MQTTConfig;
/* RemoteHardwareModule Config */
@@ -323,7 +328,7 @@ extern "C" {
/* Initializer values for message structs */
#define meshtastic_ModuleConfig_init_default {0, {meshtastic_ModuleConfig_MQTTConfig_init_default}}
#define meshtastic_ModuleConfig_MQTTConfig_init_default {0, "", "", "", 0, 0}
#define meshtastic_ModuleConfig_MQTTConfig_init_default {0, "", "", "", 0, 0, 0, ""}
#define meshtastic_ModuleConfig_RemoteHardwareConfig_init_default {0}
#define meshtastic_ModuleConfig_AudioConfig_init_default {0, 0, _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MIN, 0, 0, 0, 0}
#define meshtastic_ModuleConfig_SerialConfig_init_default {0, 0, 0, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Baud_MIN, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MIN}
@@ -333,7 +338,7 @@ extern "C" {
#define meshtastic_ModuleConfig_TelemetryConfig_init_default {0, 0, 0, 0, 0, 0, 0}
#define meshtastic_ModuleConfig_CannedMessageConfig_init_default {0, 0, 0, 0, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, 0, 0, "", 0}
#define meshtastic_ModuleConfig_init_zero {0, {meshtastic_ModuleConfig_MQTTConfig_init_zero}}
#define meshtastic_ModuleConfig_MQTTConfig_init_zero {0, "", "", "", 0, 0}
#define meshtastic_ModuleConfig_MQTTConfig_init_zero {0, "", "", "", 0, 0, 0, ""}
#define meshtastic_ModuleConfig_RemoteHardwareConfig_init_zero {0}
#define meshtastic_ModuleConfig_AudioConfig_init_zero {0, 0, _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MIN, 0, 0, 0, 0}
#define meshtastic_ModuleConfig_SerialConfig_init_zero {0, 0, 0, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Baud_MIN, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MIN}
@@ -350,6 +355,8 @@ extern "C" {
#define meshtastic_ModuleConfig_MQTTConfig_password_tag 4
#define meshtastic_ModuleConfig_MQTTConfig_encryption_enabled_tag 5
#define meshtastic_ModuleConfig_MQTTConfig_json_enabled_tag 6
#define meshtastic_ModuleConfig_MQTTConfig_tls_enabled_tag 7
#define meshtastic_ModuleConfig_MQTTConfig_root_tag 8
#define meshtastic_ModuleConfig_RemoteHardwareConfig_enabled_tag 1
#define meshtastic_ModuleConfig_AudioConfig_codec2_enabled_tag 1
#define meshtastic_ModuleConfig_AudioConfig_ptt_pin_tag 2
@@ -444,7 +451,9 @@ X(a, STATIC, SINGULAR, STRING, address, 2) \
X(a, STATIC, SINGULAR, STRING, username, 3) \
X(a, STATIC, SINGULAR, STRING, password, 4) \
X(a, STATIC, SINGULAR, BOOL, encryption_enabled, 5) \
X(a, STATIC, SINGULAR, BOOL, json_enabled, 6)
X(a, STATIC, SINGULAR, BOOL, json_enabled, 6) \
X(a, STATIC, SINGULAR, BOOL, tls_enabled, 7) \
X(a, STATIC, SINGULAR, STRING, root, 8)
#define meshtastic_ModuleConfig_MQTTConfig_CALLBACK NULL
#define meshtastic_ModuleConfig_MQTTConfig_DEFAULT NULL
@@ -562,13 +571,13 @@ extern const pb_msgdesc_t meshtastic_ModuleConfig_CannedMessageConfig_msg;
#define meshtastic_ModuleConfig_AudioConfig_size 19
#define meshtastic_ModuleConfig_CannedMessageConfig_size 49
#define meshtastic_ModuleConfig_ExternalNotificationConfig_size 40
#define meshtastic_ModuleConfig_MQTTConfig_size 201
#define meshtastic_ModuleConfig_MQTTConfig_size 220
#define meshtastic_ModuleConfig_RangeTestConfig_size 10
#define meshtastic_ModuleConfig_RemoteHardwareConfig_size 2
#define meshtastic_ModuleConfig_SerialConfig_size 26
#define meshtastic_ModuleConfig_StoreForwardConfig_size 22
#define meshtastic_ModuleConfig_TelemetryConfig_size 26
#define meshtastic_ModuleConfig_size 204
#define meshtastic_ModuleConfig_size 223
#ifdef __cplusplus
} /* extern "C" */

View File

@@ -85,6 +85,8 @@ typedef enum _meshtastic_PortNum {
/* Provides a traceroute functionality to show the route a packet towards
a certain destination would take on the mesh. */
meshtastic_PortNum_TRACEROUTE_APP = 70,
/* Aggregates edge info for the network by sending out a list of each node's neighbors */
meshtastic_PortNum_NEIGHBORINFO_APP = 71,
/* Private applications should use portnums >= 256.
To simplify initial development and testing you can use "PRIVATE_APP"
in your code without needing to rebuild protobuf files (via [regen-protos.sh](https://github.com/meshtastic/firmware/blob/master/bin/regen-protos.sh)) */

View File

@@ -234,15 +234,18 @@ void htmlDeleteDir(const char *dirname)
while (file) {
if (file.isDirectory() && !String(file.name()).endsWith(".")) {
htmlDeleteDir(file.name());
file.flush();
file.close();
} else {
String fileName = String(file.name());
file.flush();
file.close();
LOG_DEBUG(" %s\n", fileName.c_str());
FSCom.remove(fileName);
}
file = root.openNextFile();
}
root.flush();
root.close();
}
@@ -521,7 +524,7 @@ void handleFormUpload(HTTPRequest *req, HTTPResponse *res)
std::string pathname = "/static/" + filename;
// Create a new file to stream the data into
File file = FSCom.open(pathname.c_str(), "w");
File file = FSCom.open(pathname.c_str(), FILE_O_WRITE);
size_t fileLength = 0;
didwrite = true;
@@ -536,6 +539,7 @@ void handleFormUpload(HTTPRequest *req, HTTPResponse *res)
// Abort the transfer if there is less than 50k space left on the filesystem.
if (FSCom.totalBytes() - FSCom.usedBytes() < 51200) {
file.flush();
file.close();
res->println("<p>Write aborted! Reserving 50k on filesystem.</p>");
@@ -553,6 +557,7 @@ void handleFormUpload(HTTPRequest *req, HTTPResponse *res)
}
// enableLoopWDT();
file.flush();
file.close();
res->printf("<p>Saved %d bytes to %s</p>", (int)fileLength, pathname.c_str());
}
@@ -622,10 +627,10 @@ void handleReport(HTTPRequest *req, HTTPResponse *res)
// data->memory
JSONObject jsonObjMemory;
jsonObjMemory["heap_total"] = new JSONValue((int)ESP.getHeapSize());
jsonObjMemory["heap_free"] = new JSONValue((int)ESP.getFreeHeap());
jsonObjMemory["psram_total"] = new JSONValue((int)ESP.getPsramSize());
jsonObjMemory["psram_free"] = new JSONValue((int)ESP.getFreePsram());
jsonObjMemory["heap_total"] = new JSONValue((int)memGet.getHeapSize());
jsonObjMemory["heap_free"] = new JSONValue((int)memGet.getFreeHeap());
jsonObjMemory["psram_total"] = new JSONValue((int)memGet.getPsramSize());
jsonObjMemory["psram_free"] = new JSONValue((int)memGet.getFreePsram());
jsonObjMemory["fs_total"] = new JSONValue((int)FSCom.totalBytes());
jsonObjMemory["fs_used"] = new JSONValue((int)FSCom.usedBytes());
jsonObjMemory["fs_free"] = new JSONValue(int(FSCom.totalBytes() - FSCom.usedBytes()));
@@ -645,7 +650,7 @@ void handleReport(HTTPRequest *req, HTTPResponse *res)
// data->radio
JSONObject jsonObjRadio;
jsonObjRadio["frequency"] = new JSONValue(RadioLibInterface::instance->getFreq());
jsonObjRadio["lora_channel"] = new JSONValue((int)RadioLibInterface::instance->getChannelNum());
jsonObjRadio["lora_channel"] = new JSONValue((int)RadioLibInterface::instance->getChannelNum() + 1);
// collect data to inner data object
JSONObject jsonObjInner;
@@ -833,7 +838,7 @@ void handleScanNetworks(HTTPRequest *req, HTTPResponse *res)
if (WiFi.encryptionType(i) != WIFI_AUTH_OPEN) {
JSONObject thisNetwork;
thisNetwork["ssid"] = new JSONValue(ssidArray);
thisNetwork["rssi"] = new JSONValue(WiFi.RSSI(i));
thisNetwork["rssi"] = new JSONValue(int(WiFi.RSSI(i)));
networkObjs.push_back(new JSONValue(thisNetwork));
}
// Yield some cpu cycles to IP stack.

View File

@@ -39,9 +39,9 @@ static void writeSecret(char *buf, size_t bufsz, const char *currentVal)
}
/**
* @brief Handle recieved protobuf message
* @brief Handle received protobuf message
*
* @param mp Recieved MeshPacket
* @param mp Received MeshPacket
* @param r Decoded AdminMessage
* @return bool
*/

View File

@@ -446,8 +446,6 @@ int CannedMessageModule::getPrevIndex()
void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
displayedNodeNum = 0; // Not currently showing a node pane
char buffer[50];
if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE) {

View File

@@ -8,6 +8,17 @@
#include "mesh/generated/meshtastic/rtttl.pb.h"
#include <Arduino.h>
#include "main.h"
#ifdef RAK4630
#include <NCP5623.h>
NCP5623 rgb;
uint8_t red = 0;
uint8_t green = 0;
uint8_t blue = 0;
#endif
#ifndef PIN_BUZZER
#define PIN_BUZZER false
#endif
@@ -73,6 +84,15 @@ int32_t ExternalNotificationModule::runOnce()
millis()) {
getExternal(2) ? setExternalOff(2) : setExternalOn(2);
}
#ifdef RAK4630
if (rgb_found.type == ScanI2C::NCP5623) {
green = (green + 50) % 255;
red = abs(red - green) % 255;
blue = abs(blue / red) % 255;
rgb.setColor(red, green, blue);
}
#endif
}
// now let the PWM buzzer play
@@ -84,6 +104,7 @@ int32_t ExternalNotificationModule::runOnce()
rtttl::begin(config.device.buzzer_gpio, rtttlConfig.ringtone);
}
}
return 25;
}
}
@@ -106,6 +127,11 @@ void ExternalNotificationModule::setExternalOn(uint8_t index)
digitalWrite(output, (moduleConfig.external_notification.active ? true : false));
break;
}
#ifdef RAK4630
if (rgb_found.type == ScanI2C::NCP5623) {
rgb.setColor(red, green, blue);
}
#endif
}
void ExternalNotificationModule::setExternalOff(uint8_t index)
@@ -126,6 +152,15 @@ void ExternalNotificationModule::setExternalOff(uint8_t index)
digitalWrite(output, (moduleConfig.external_notification.active ? false : true));
break;
}
#ifdef RAK4630
if (rgb_found.type == ScanI2C::NCP5623) {
red = 0;
green = 0;
blue = 0;
rgb.setColor(red, green, blue);
}
#endif
}
bool ExternalNotificationModule::getExternal(uint8_t index)
@@ -200,6 +235,12 @@ ExternalNotificationModule::ExternalNotificationModule()
LOG_INFO("Using Pin %i in PWM mode\n", config.device.buzzer_gpio);
}
}
#ifdef RAK4630
if (rgb_found.type == ScanI2C::NCP5623) {
rgb.begin();
rgb.setCurrent(10);
}
#endif
} else {
LOG_INFO("External Notification Module Disabled\n");
disable();
@@ -300,7 +341,6 @@ ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshP
nagCycleCutoff = millis() + moduleConfig.external_notification.output_ms;
}
}
setIntervalFromNow(0); // run once so we know if we should do something
}

View File

@@ -72,7 +72,8 @@ void setupModules()
new AirQualityTelemetryModule();
}
#endif
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(TTGO_T_ECHO) && !defined(CONFIG_IDF_TARGET_ESP32S2)
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(TTGO_T_ECHO) && !defined(CONFIG_IDF_TARGET_ESP32S2) && \
!defined(CONFIG_IDF_TARGET_ESP32C3)
new SerialModule();
#endif
#ifdef ARCH_ESP32

View File

@@ -12,7 +12,7 @@ bool NodeInfoModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, mes
{
auto p = *pptr;
nodeDB.updateUser(getFrom(&mp), p);
bool hasChanged = nodeDB.updateUser(getFrom(&mp), p);
bool wasBroadcast = mp.to == NODENUM_BROADCAST;
@@ -23,11 +23,15 @@ bool NodeInfoModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, mes
screen->print(lcd.c_str());
}
// if user has changed while packet was not for us, inform phone
if (hasChanged && !wasBroadcast && mp.to != nodeDB.getNodeNum())
service.sendToPhone(packetPool.allocCopy(mp));
// LOG_DEBUG("did handleReceived\n");
return false; // Let others look at this message also if they want
}
void NodeInfoModule::sendOurNodeInfo(NodeNum dest, bool wantReplies)
void NodeInfoModule::sendOurNodeInfo(NodeNum dest, bool wantReplies, uint8_t channel)
{
// cancel any not yet sent (now stale) position packets
if (prevPacketId) // if we wrap around to zero, we'll simply fail to cancel in that rare case (no big deal)
@@ -38,6 +42,11 @@ void NodeInfoModule::sendOurNodeInfo(NodeNum dest, bool wantReplies)
p->to = dest;
p->decoded.want_response = wantReplies;
p->priority = meshtastic_MeshPacket_Priority_BACKGROUND;
if (channel > 0) {
LOG_DEBUG("sending ourNodeInfo to channel %d\n", channel);
p->channel = channel;
}
prevPacketId = p->id;
service.sendToMesh(p);

View File

@@ -20,7 +20,7 @@ class NodeInfoModule : public ProtobufModule<meshtastic_User>, private concurren
/**
* Send our NodeInfo into the mesh
*/
void sendOurNodeInfo(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false);
void sendOurNodeInfo(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false, uint8_t channel = 0);
protected:
/** Called to handle a particular incoming message

View File

@@ -120,7 +120,7 @@ meshtastic_MeshPacket *PositionModule::allocReply()
return allocDataProtobuf(p);
}
void PositionModule::sendOurPosition(NodeNum dest, bool wantReplies)
void PositionModule::sendOurPosition(NodeNum dest, bool wantReplies, uint8_t channel)
{
// cancel any not yet sent (now stale) position packets
if (prevPacketId) // if we wrap around to zero, we'll simply fail to cancel in that rare case (no big deal)
@@ -135,6 +135,9 @@ void PositionModule::sendOurPosition(NodeNum dest, bool wantReplies)
p->priority = meshtastic_MeshPacket_Priority_BACKGROUND;
prevPacketId = p->id;
if (channel > 0)
p->channel = channel;
service.sendToMesh(p, RX_SRC_LOCAL, true);
}
@@ -144,10 +147,10 @@ int32_t PositionModule::runOnce()
// We limit our GPS broadcasts to a max rate
uint32_t now = millis();
uint32_t intervalMs = config.position.position_broadcast_secs > 0 ? config.position.position_broadcast_secs * 1000
: default_broadcast_interval_secs * 1000;
if (lastGpsSend == 0 || (now - lastGpsSend) >= intervalMs) {
uint32_t intervalMs = getConfiguredOrDefaultMs(config.position.position_broadcast_secs, default_broadcast_interval_secs);
uint32_t msSinceLastSend = now - lastGpsSend;
if (lastGpsSend == 0 || msSinceLastSend >= intervalMs) {
// Only send packets if the channel is less than 40% utilized.
if (airTime->isTxAllowedChannelUtil()) {
if (node->has_position && (node->position.latitude_i != 0 || node->position.longitude_i != 0)) {
@@ -165,39 +168,32 @@ int32_t PositionModule::runOnce()
}
}
} else if (config.position.position_broadcast_smart_enabled) {
// Only send packets if the channel is less than 25% utilized.
if (airTime->isTxAllowedChannelUtil(true)) {
// Only send packets if the channel is less than 25% utilized or we're a tracker.
if (airTime->isTxAllowedChannelUtil(config.device.role != meshtastic_Config_DeviceConfig_Role_TRACKER)) {
meshtastic_NodeInfo *node2 = service.refreshMyNodeInfo(); // should guarantee there is now a position
if (node2->has_position && (node2->position.latitude_i != 0 || node2->position.longitude_i != 0)) {
// The minimum distance to travel before we are able to send a new position packet.
const uint32_t distanceTravelMinimum = 30;
const uint32_t distanceTravelThreshold =
config.position.broadcast_smart_minimum_distance > 0 ? config.position.broadcast_smart_minimum_distance : 100;
// The minimum time that would pass before we are able to send a new position packet.
const uint32_t timeTravelMinimum = 30;
// The minimum time (in seconds) that would pass before we are able to send a new position packet.
const uint32_t minimumTimeThreshold =
getConfiguredOrDefaultMs(config.position.broadcast_smart_minimum_interval_secs, 30);
// Determine the distance in meters between two points on the globe
float distance = GeoCoord::latLongToMeter(lastGpsLatitude * 1e-7, lastGpsLongitude * 1e-7,
node->position.latitude_i * 1e-7, node->position.longitude_i * 1e-7);
float distanceTraveledSinceLastSend =
GeoCoord::latLongToMeter(lastGpsLatitude * 1e-7, lastGpsLongitude * 1e-7, node->position.latitude_i * 1e-7,
node->position.longitude_i * 1e-7);
// Yes, this has a bunch of magic numbers. Sorry. This is to make the scale non-linear.
const float distanceTravelMath = 1203 / (sqrt(pow(myNodeInfo.bitrate, 1.5) / 1.1));
uint32_t distanceTravelThreshold =
(distanceTravelMath >= distanceTravelMinimum) ? distanceTravelMath : distanceTravelMinimum;
// Yes, this has a bunch of magic numbers. Sorry.
uint32_t timeTravel =
((1500 / myNodeInfo.bitrate) >= timeTravelMinimum) ? (1500 / myNodeInfo.bitrate) : timeTravelMinimum;
// If the distance traveled since the last update is greater than distanceTravelMinimum meters
// and it's been at least timeTravelMinimum seconds since the last update
if ((abs(distance) >= distanceTravelThreshold) && (now - lastGpsSend) >= (timeTravel * 1000)) {
if ((abs(distanceTraveledSinceLastSend) >= distanceTravelThreshold) && msSinceLastSend >= minimumTimeThreshold) {
bool requestReplies = currentGeneration != radioGeneration;
currentGeneration = radioGeneration;
LOG_INFO("Sending smart pos@%x:6 to mesh (wantReplies=%d, d=%d, dtt=%d, tt=%d)\n", node2->position.timestamp,
requestReplies, distance, distanceTravelThreshold, timeTravel);
LOG_INFO("Sending smart pos@%x:6 to mesh (distanceTraveled=%fm, minDistanceThreshold=%im, timeElapsed=%ims, "
"minTimeInterval=%ims)\n",
node2->position.timestamp, abs(distanceTraveledSinceLastSend), distanceTravelThreshold,
msSinceLastSend, minimumTimeThreshold);
sendOurPosition(NODENUM_BROADCAST, requestReplies);
// Set the current coords as our last ones, after we've compared distance with current and decided to send

View File

@@ -29,7 +29,7 @@ class PositionModule : public ProtobufModule<meshtastic_Position>, private concu
/**
* Send our position into the mesh
*/
void sendOurPosition(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false);
void sendOurPosition(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false, uint8_t channel = 0);
protected:
/** Called to handle a particular incoming message

View File

@@ -18,7 +18,7 @@
static void pinModes(uint64_t mask, uint8_t mode)
{
for (uint64_t i = 0; i < NUM_GPIOS; i++) {
if (mask & (1 << i)) {
if (mask & (1ULL << i)) {
pinMode(i, mode);
}
}
@@ -29,13 +29,10 @@ static uint64_t digitalReads(uint64_t mask)
{
uint64_t res = 0;
// The Arduino docs show to run pinMode(). But, when testing, found it is best not to.
// If the line below is uncommented, read will flip the pin to the default of the second
// argument in pinModes(), which will make the read turn the PIN "on".
// pinModes(mask, INPUT_PULLUP);
pinModes(mask, INPUT_PULLUP);
for (uint64_t i = 0; i < NUM_GPIOS; i++) {
uint64_t m = 1 << i;
uint64_t m = 1ULL << i;
if (mask & m) {
if (digitalRead(i)) {
res |= m;
@@ -64,7 +61,7 @@ bool RemoteHardwareModule::handleReceivedProtobuf(const meshtastic_MeshPacket &r
screen->print("Write GPIOs\n");
for (uint8_t i = 0; i < NUM_GPIOS; i++) {
uint64_t mask = 1 << i;
uint64_t mask = 1ULL << i;
if (p.gpio_mask & mask) {
digitalWrite(i, (p.gpio_value & mask) ? 1 : 0);
}

View File

@@ -44,7 +44,8 @@
*/
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(TTGO_T_ECHO) && !defined(CONFIG_IDF_TARGET_ESP32S2)
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(TTGO_T_ECHO) && !defined(CONFIG_IDF_TARGET_ESP32S2) && \
!defined(CONFIG_IDF_TARGET_ESP32C3)
#define RX_BUFFER 128
#define TIMEOUT 250

View File

@@ -8,7 +8,8 @@
#include <Arduino.h>
#include <functional>
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(TTGO_T_ECHO) && !defined(CONFIG_IDF_TARGET_ESP32S2)
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(TTGO_T_ECHO) && !defined(CONFIG_IDF_TARGET_ESP32S2) && \
!defined(CONFIG_IDF_TARGET_ESP32C3)
class SerialModule : public StreamAPI, private concurrency::OSThread
{

View File

@@ -10,7 +10,7 @@
#include <OLEDDisplay.h>
#include <OLEDDisplayUi.h>
#define MAGIC_USB_BATTERY_LEVEL 111
#define MAGIC_USB_BATTERY_LEVEL 101
int32_t DeviceTelemetryModule::runOnce()
{

View File

@@ -1,18 +1,26 @@
#include "BME680Sensor.h"
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "FSCommon.h"
#include "TelemetrySensor.h"
#include "configuration.h"
#include <Adafruit_BME680.h>
BME680Sensor::BME680Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_BME680, "BME680") {}
int32_t BME680Sensor::runOnce()
{
LOG_INFO("Init sensor: %s\n", sensorName);
LOG_INFO("Init sensor: %s with the BSEC Library\n", sensorName);
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
status = bme680.begin(nodeTelemetrySensorsMap[sensorType]);
bme680.begin(nodeTelemetrySensorsMap[sensorType], Wire);
if (bme680.bsecStatus == BSEC_OK) {
bme680.setConfig(bsec_config_iaq);
loadState();
bme680.updateSubscription(sensorList, 13, BSEC_SAMPLE_RATE_LP);
status = 1;
} else {
status = 0;
}
return initI2CSensor();
}
@@ -21,11 +29,76 @@ void BME680Sensor::setup() {}
bool BME680Sensor::getMetrics(meshtastic_Telemetry *measurement)
{
bme680.performReading();
bme680.run();
measurement->variant.environment_metrics.temperature = bme680.temperature;
measurement->variant.environment_metrics.relative_humidity = bme680.humidity;
measurement->variant.environment_metrics.barometric_pressure = bme680.pressure / 100.0F;
measurement->variant.environment_metrics.gas_resistance = bme680.gas_resistance / 1000.0;
measurement->variant.environment_metrics.gas_resistance = bme680.gasResistance / 1000.0;
// Check if we need to save state to filesystem (every STATE_SAVE_PERIOD ms)
updateState();
return true;
}
void BME680Sensor::loadState()
{
#ifdef FSCom
auto file = FSCom.open(bsecConfigFileName, FILE_O_READ);
if (file) {
file.read((uint8_t *)&bsecState, BSEC_MAX_STATE_BLOB_SIZE);
file.close();
bme680.setState(bsecState);
LOG_INFO("%s state read from %s.\n", sensorName, bsecConfigFileName);
} else {
LOG_INFO("No %s state found (File: %s).\n", sensorName, bsecConfigFileName);
}
#else
LOG_ERROR("ERROR: Filesystem not implemented\n");
#endif
}
void BME680Sensor::updateState()
{
#ifdef FSCom
bool update = false;
if (stateUpdateCounter == 0) {
/* First state update when IAQ accuracy is >= 3 */
if (bme680.iaqAccuracy >= 3) {
LOG_DEBUG("%s state update IAQ accuracy %u >= 3\n", sensorName, bme680.iaqAccuracy);
update = true;
stateUpdateCounter++;
} else {
LOG_DEBUG("%s not updated, IAQ accuracy is %u >= 3\n", sensorName, bme680.iaqAccuracy);
}
} else {
/* Update every STATE_SAVE_PERIOD minutes */
if ((stateUpdateCounter * STATE_SAVE_PERIOD) < millis()) {
LOG_DEBUG("%s state update every %d minutes\n", sensorName, STATE_SAVE_PERIOD);
update = true;
stateUpdateCounter++;
}
}
if (update) {
bme680.getState(bsecState);
std::string filenameTmp = bsecConfigFileName;
filenameTmp += ".tmp";
auto file = FSCom.open(bsecConfigFileName, FILE_O_WRITE);
if (file) {
LOG_INFO("%s state write to %s.\n", sensorName, bsecConfigFileName);
file.write((uint8_t *)&bsecState, BSEC_MAX_STATE_BLOB_SIZE);
file.flush();
file.close();
// brief window of risk here ;-)
if (FSCom.exists(bsecConfigFileName) && !FSCom.remove(bsecConfigFileName))
LOG_WARN("Can't remove old state file\n");
if (!renameFile(filenameTmp.c_str(), bsecConfigFileName))
LOG_ERROR("Error: can't rename new state file\n");
} else {
LOG_INFO("Can't write %s state (File: %s).\n", sensorName, bsecConfigFileName);
}
}
#else
LOG_ERROR("ERROR: Filesystem not implemented\n");
#endif
}

View File

@@ -1,14 +1,38 @@
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include <Adafruit_BME680.h>
#include <bsec.h>
#define STATE_SAVE_PERIOD UINT32_C(360 * 60 * 1000) // That's 6 hours worth of millis()
const uint8_t bsec_config_iaq[] = {
#include <config/generic_33v_3s_4d/bsec_iaq.txt>
};
class BME680Sensor : virtual public TelemetrySensor
{
private:
Adafruit_BME680 bme680;
Bsec bme680;
protected:
virtual void setup() override;
const char *bsecConfigFileName = "/prefs/bsec.dat";
uint8_t bsecState[BSEC_MAX_STATE_BLOB_SIZE] = {0};
uint16_t stateUpdateCounter = 0;
bsec_virtual_sensor_t sensorList[13] = {BSEC_OUTPUT_IAQ,
BSEC_OUTPUT_STATIC_IAQ,
BSEC_OUTPUT_CO2_EQUIVALENT,
BSEC_OUTPUT_BREATH_VOC_EQUIVALENT,
BSEC_OUTPUT_RAW_TEMPERATURE,
BSEC_OUTPUT_RAW_PRESSURE,
BSEC_OUTPUT_RAW_HUMIDITY,
BSEC_OUTPUT_RAW_GAS,
BSEC_OUTPUT_STABILIZATION_STATUS,
BSEC_OUTPUT_RUN_IN_STATUS,
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE,
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY,
BSEC_OUTPUT_GAS_PERCENTAGE};
void loadState();
void updateState();
public:
BME680Sensor();

View File

@@ -15,7 +15,7 @@ ProcessMessage TextMessageModule::handleReceived(const meshtastic_MeshPacket &mp
devicestate.rx_text_message = mp;
devicestate.has_rx_text_message = true;
powerFSM.trigger(EVENT_RECEIVED_TEXT_MSG);
powerFSM.trigger(EVENT_RECEIVED_MSG);
notifyObservers(&mp);
return ProcessMessage::CONTINUE; // Let others look at this message also if they want

View File

@@ -10,6 +10,12 @@ ProcessMessage WaypointModule::handleReceived(const meshtastic_MeshPacket &mp)
auto &p = mp.decoded;
LOG_INFO("Received waypoint msg from=0x%0x, id=0x%x, msg=%.*s\n", mp.from, mp.id, p.payload.size, p.payload.bytes);
// We only store/display messages destined for us.
// Keep a copy of the most recent text message.
devicestate.rx_waypoint = mp;
devicestate.has_rx_waypoint = true;
powerFSM.trigger(EVENT_RECEIVED_MSG);
notifyObservers(&mp);
return ProcessMessage::CONTINUE; // Let others look at this message also if they want

View File

@@ -153,8 +153,6 @@ AudioModule::AudioModule() : SinglePortModule("AudioModule", meshtastic_PortNum_
void AudioModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
displayedNodeNum = 0; // Not currently showing a node pane
char buffer[50];
display->setTextAlignment(TEXT_ALIGN_LEFT);

View File

@@ -226,7 +226,7 @@ bool RangeTestModuleRadio::appendFile(const meshtastic_MeshPacket &mp)
} else {
LOG_ERROR("File write failed\n");
}
fileToWrite.flush();
fileToWrite.close();
}
@@ -275,6 +275,7 @@ bool RangeTestModuleRadio::appendFile(const meshtastic_MeshPacket &mp)
// TODO: If quotes are found in the payload, it has to be escaped.
fileToAppend.printf("\"%s\"\n", p.payload.bytes);
fileToAppend.flush();
fileToAppend.close();
return 1;

View File

@@ -5,6 +5,7 @@
#include "Router.h"
#include "airtime.h"
#include "configuration.h"
#include "memGet.h"
#include "mesh-pb-constants.h"
#include "mesh/generated/meshtastic/storeforward.pb.h"
#include "modules/ModuleDev.h"
@@ -63,8 +64,8 @@ void StoreForwardModule::populatePSRAM()
https://learn.upesy.com/en/programmation/psram.html#psram-tab
*/
LOG_DEBUG("*** Before PSRAM initilization: heap %d/%d PSRAM %d/%d\n", ESP.getFreeHeap(), ESP.getHeapSize(),
ESP.getFreePsram(), ESP.getPsramSize());
LOG_DEBUG("*** Before PSRAM initilization: heap %d/%d PSRAM %d/%d\n", memGet.getFreeHeap(), memGet.getHeapSize(),
memGet.getFreePsram(), memGet.getPsramSize());
this->packetHistoryTXQueue =
static_cast<PacketHistoryStruct *>(ps_calloc(this->historyReturnMax, sizeof(PacketHistoryStruct)));
@@ -72,13 +73,14 @@ void StoreForwardModule::populatePSRAM()
/* Use a maximum of 2/3 the available PSRAM unless otherwise specified.
Note: This needs to be done after every thing that would use PSRAM
*/
uint32_t numberOfPackets = (this->records ? this->records : (((ESP.getFreePsram() / 3) * 2) / sizeof(PacketHistoryStruct)));
uint32_t numberOfPackets =
(this->records ? this->records : (((memGet.getFreePsram() / 3) * 2) / sizeof(PacketHistoryStruct)));
this->records = numberOfPackets;
this->packetHistory = static_cast<PacketHistoryStruct *>(ps_calloc(numberOfPackets, sizeof(PacketHistoryStruct)));
LOG_DEBUG("*** After PSRAM initilization: heap %d/%d PSRAM %d/%d\n", ESP.getFreeHeap(), ESP.getHeapSize(), ESP.getFreePsram(),
ESP.getPsramSize());
LOG_DEBUG("*** After PSRAM initilization: heap %d/%d PSRAM %d/%d\n", memGet.getFreeHeap(), memGet.getHeapSize(),
memGet.getFreePsram(), memGet.getPsramSize());
LOG_DEBUG("*** numberOfPackets for packetHistory - %u\n", numberOfPackets);
}
@@ -445,8 +447,8 @@ StoreForwardModule::StoreForwardModule()
if ((config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER) ||
(config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER_CLIENT)) {
LOG_INFO("*** Initializing Store & Forward Module in Router mode\n");
if (ESP.getPsramSize() > 0) {
if (ESP.getFreePsram() >= 1024 * 1024) {
if (memGet.getPsramSize() > 0) {
if (memGet.getFreePsram() >= 1024 * 1024) {
// Do the startup here

View File

@@ -19,10 +19,6 @@ const int reconnectMax = 5;
MQTT *mqtt;
std::string statusTopic = "msh/2/stat/";
std::string cryptTopic = "msh/2/c/"; // msh/2/c/CHANNELID/NODEID
std::string jsonTopic = "msh/2/json/"; // msh/2/json/CHANNELID/NODEID
static MemoryDynamic<meshtastic_ServiceEnvelope> staticMqttPool;
Allocator<meshtastic_ServiceEnvelope> &mqttPool = staticMqttPool;
@@ -164,6 +160,16 @@ MQTT::MQTT() : concurrency::OSThread("mqtt"), pubSub(mqttClient), mqttQueue(MAX_
assert(!mqtt);
mqtt = this;
if (*moduleConfig.mqtt.root) {
statusTopic = moduleConfig.mqtt.root + statusTopic;
cryptTopic = moduleConfig.mqtt.root + cryptTopic;
jsonTopic = moduleConfig.mqtt.root + jsonTopic;
} else {
statusTopic = "msh" + statusTopic;
cryptTopic = "msh" + cryptTopic;
jsonTopic = "msh" + jsonTopic;
}
pubSub.setCallback(mqttCallback);
// preflightSleepObserver.observe(&preflightSleep);
@@ -192,6 +198,26 @@ void MQTT::reconnect()
mqttPassword = moduleConfig.mqtt.password;
}
#if HAS_WIFI && !defined(ARCH_PORTDUINO)
if (moduleConfig.mqtt.tls_enabled) {
// change default for encrypted to 8883
try {
serverPort = 8883;
wifiSecureClient.setInsecure();
pubSub.setClient(wifiSecureClient);
LOG_INFO("Using TLS-encrypted session\n");
} catch (const std::exception &e) {
LOG_ERROR("MQTT ERROR: %s\n", e.what());
}
} else {
LOG_INFO("Using non-TLS-encrypted session\n");
pubSub.setClient(mqttClient);
}
#else
pubSub.setClient(mqttClient);
#endif
String server = String(serverAddr);
int delimIndex = server.indexOf(':');
if (delimIndex > 0) {
@@ -528,4 +554,4 @@ std::string MQTT::downstreamPacketToJson(meshtastic_MeshPacket *mp)
delete value;
return jsonStr;
}
}

View File

@@ -8,6 +8,9 @@
#include <PubSubClient.h>
#if HAS_WIFI
#include <WiFiClient.h>
#if !defined(ARCH_PORTDUINO)
#include <WiFiClientSecure.h>
#endif
#endif
#if HAS_ETHERNET
#include <EthernetClient.h>
@@ -23,9 +26,11 @@ class MQTT : private concurrency::OSThread
{
// supposedly the current version is busted:
// http://www.iotsharing.com/2017/08/how-to-use-esp32-mqtts-with-mqtts-mosquitto-broker-tls-ssl.html
// WiFiClientSecure wifiClient;
#if HAS_WIFI
WiFiClient mqttClient;
#if !defined(ARCH_PORTDUINO)
WiFiClientSecure wifiSecureClient;
#endif
#endif
#if HAS_ETHERNET
EthernetClient mqttClient;
@@ -64,6 +69,9 @@ class MQTT : private concurrency::OSThread
virtual int32_t runOnce() override;
private:
std::string statusTopic = "/2/stat/";
std::string cryptTopic = "/2/c/"; // msh/2/c/CHANNELID/NODEID
std::string jsonTopic = "/2/json/"; // msh/2/json/CHANNELID/NODEID
/** return true if we have a channel that wants uplink/downlink
*/
bool wantsLink() const;
@@ -87,4 +95,4 @@ class MQTT : private concurrency::OSThread
void mqttInit();
extern MQTT *mqtt;
extern MQTT *mqtt;

View File

@@ -85,7 +85,6 @@ void esp32Setup()
{
uint32_t seed = esp_random();
LOG_DEBUG("Setting random seed %u\n", seed);
randomSeed(seed); // ESP docs say this is fairly random
LOG_DEBUG("Total heap: %d\n", ESP.getHeapSize());
LOG_DEBUG("Free heap: %d\n", ESP.getFreeHeap());
@@ -163,7 +162,7 @@ void esp32Loop()
// radio.radioIf.canSleep();
}
void cpuDeepSleep(uint64_t msecToWake)
void cpuDeepSleep(uint32_t msecToWake)
{
/*
Some ESP32 IOs have internal pullups or pulldowns, which are enabled by default.
@@ -178,6 +177,7 @@ void cpuDeepSleep(uint64_t msecToWake)
Note: we don't isolate pins that are used for the LORA, LED, i2c, spi or the wake button
*/
#if SOC_RTCIO_HOLD_SUPPORTED
static const uint8_t rtcGpios[] = {/* 0, */ 2,
/* 4, */
#ifndef USE_JTAG
@@ -191,6 +191,7 @@ void cpuDeepSleep(uint64_t msecToWake)
for (int i = 0; i < sizeof(rtcGpios); i++)
rtc_gpio_isolate((gpio_num_t)rtcGpios[i]);
#endif
// FIXME, disable internal rtc pullups/pulldowns on the non isolated pins. for inputs that we aren't using
// to detect wake and in normal operation the external part drives them hard.
@@ -200,7 +201,9 @@ void cpuDeepSleep(uint64_t msecToWake)
#ifdef BUTTON_PIN
// Only GPIOs which are have RTC functionality can be used in this bit map: 0,2,4,12-15,25-27,32-39.
uint64_t gpioMask = (1ULL << BUTTON_PIN);
#if SOC_RTCIO_HOLD_SUPPORTED
uint64_t gpioMask = (1ULL << config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN);
#endif
#ifdef BUTTON_NEED_PULLUP
gpio_pullup_en((gpio_num_t)BUTTON_PIN);
@@ -210,9 +213,11 @@ void cpuDeepSleep(uint64_t msecToWake)
// FIXME change polarity in hw so we can wake on ANY_HIGH instead - that would allow us to use all three buttons (instead of
// just the first) gpio_pullup_en((gpio_num_t)BUTTON_PIN);
#if SOC_PM_SUPPORT_EXT_WAKEUP
esp_sleep_enable_ext1_wakeup(gpioMask, ESP_EXT1_WAKEUP_ALL_LOW);
#endif
#endif
esp_sleep_enable_timer_wakeup(msecToWake * 1000ULL); // call expects usecs
esp_deep_sleep_start(); // TBD mA sleep current (battery)
}
}

View File

@@ -92,12 +92,12 @@ void startAdv(void)
Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
// IncludeService UUID
Bluefruit.ScanResponse.addService(meshBleService);
// Bluefruit.ScanResponse.addService(meshBleService);
Bluefruit.ScanResponse.addTxPower();
Bluefruit.ScanResponse.addName();
// Include Name
Bluefruit.Advertising.addName();
// Bluefruit.Advertising.addName();
Bluefruit.Advertising.addService(meshBleService);
/* Start Advertising

View File

@@ -90,7 +90,7 @@ extern "C" void HardFault_Handler(void)
asm volatile(" mrs r0,msp\n"
" b HardFault_Impl \n");
}
#else
#elif !defined(ARCH_NRF52)
/* The prototype shows it is a naked function - in effect this is just an
assembly function. */

View File

@@ -155,7 +155,7 @@ void nrf52Setup()
nRFCrypto.end();
}
void cpuDeepSleep(uint64_t msecToWake)
void cpuDeepSleep(uint32_t msecToWake)
{
// FIXME, configure RTC or button press to wake us
// FIXME, power down SPI, I2C, RAMs

View File

@@ -16,7 +16,7 @@ void setBluetoothEnable(bool on)
// not needed
}
void cpuDeepSleep(uint64_t msecs)
void cpuDeepSleep(uint32_t msecs)
{
notImplemented("cpuDeepSleep");
}

View File

@@ -7,7 +7,7 @@ void setBluetoothEnable(bool on)
// not needed
}
void cpuDeepSleep(uint64_t msecs)
void cpuDeepSleep(uint32_t msecs)
{
// not needed
}

View File

@@ -15,7 +15,7 @@ void getMacAddr(uint8_t *dmac)
dmac[i] = i;
}
void cpuDeepSleep(uint64_t msecToWake) {}
void cpuDeepSleep(uint32_t msecToWake) {}
/* pacify libc_nano */
extern "C" {

View File

@@ -19,6 +19,10 @@
esp_sleep_source_t wakeCause; // the reason we booted this time
#endif
#ifndef INCLUDE_vTaskSuspend
#define INCLUDE_vTaskSuspend 0
#endif
#ifdef HAS_PMU
#include "XPowersLibInterface.hpp"
extern XPowersLibInterface *PMU;
@@ -61,13 +65,15 @@ void setCPUFast(bool on)
* all WiFi use cases.
* (Added: Dec 23, 2021 by Jm Casler)
*/
#ifndef CONFIG_IDF_TARGET_ESP32C3
LOG_DEBUG("Setting CPU to 240mhz because WiFi is in use.\n");
setCpuFrequencyMhz(240);
#endif
return;
}
// The Heltec LORA32 V1 runs at 26 MHz base frequency and doesn't react well to switching to 80 MHz...
#ifndef ARDUINO_HELTEC_WIFI_LORA_32
#if !defined(ARDUINO_HELTEC_WIFI_LORA_32) && !defined(CONFIG_IDF_TARGET_ESP32C3)
setCpuFrequencyMhz(on ? 240 : 80);
#endif
@@ -97,10 +103,15 @@ void setGPSPower(bool on)
if (pmu_found && PMU) {
uint8_t model = PMU->getChipModel();
if (model == XPOWERS_AXP2101) {
#if (HW_VENDOR == meshtastic_HardwareModel_TBEAM)
// t-beam v1.2 GNSS power channel
on ? PMU->enablePowerOutput(XPOWERS_ALDO3) : PMU->disablePowerOutput(XPOWERS_ALDO3);
#elif (HW_VENDOR == meshtastic_HardwareModel_LILYGO_TBEAM_S3_CORE)
// t-beam-s3-core GNSS power channel
on ? PMU->enablePowerOutput(XPOWERS_ALDO4) : PMU->disablePowerOutput(XPOWERS_ALDO4);
#endif
} else if (model == XPOWERS_AXP192) {
// t-beam GNSS power channel
// t-beam v1.1 GNSS power channel
on ? PMU->enablePowerOutput(XPOWERS_LDO3) : PMU->disablePowerOutput(XPOWERS_LDO3);
}
}
@@ -194,9 +205,13 @@ void doGPSpowersave(bool on)
#endif
}
void doDeepSleep(uint64_t msecToWake)
void doDeepSleep(uint32_t msecToWake)
{
LOG_INFO("Entering deep sleep for %lu seconds\n", msecToWake / 1000);
if (INCLUDE_vTaskSuspend && (msecToWake == portMAX_DELAY)) {
LOG_INFO("Entering deep sleep forever\n");
} else {
LOG_INFO("Entering deep sleep for %u seconds\n", msecToWake / 1000);
}
// not using wifi yet, but once we are this is needed to shutoff the radio hw
// esp_wifi_stop();
@@ -235,8 +250,14 @@ void doDeepSleep(uint64_t msecToWake)
uint8_t model = PMU->getChipModel();
if (model == XPOWERS_AXP2101) {
#if (HW_VENDOR == meshtastic_HardwareModel_TBEAM)
// t-beam v1.2 radio power channel
PMU->disablePowerOutput(XPOWERS_ALDO2); // lora radio power channel
#elif (HW_VENDOR == meshtastic_HardwareModel_LILYGO_TBEAM_S3_CORE)
PMU->disablePowerOutput(XPOWERS_ALDO3); // lora radio power channel
#endif
} else if (model == XPOWERS_AXP192) {
// t-beam v1.1 radio power channel
PMU->disablePowerOutput(XPOWERS_LDO2); // lora radio power channel
}
}
@@ -288,7 +309,16 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r
// assert(esp_sleep_enable_uart_wakeup(0) == ESP_OK);
#endif
#ifdef BUTTON_PIN
gpio_wakeup_enable((gpio_num_t)BUTTON_PIN, GPIO_INTR_LOW_LEVEL); // when user presses, this button goes low
#if SOC_PM_SUPPORT_EXT_WAKEUP
esp_sleep_enable_ext0_wakeup((gpio_num_t)(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN),
LOW); // when user presses, this button goes low
#else
esp_sleep_enable_gpio_wakeup();
gpio_wakeup_enable((gpio_num_t)BUTTON_PIN, GPIO_INTR_LOW_LEVEL);
#endif
#endif
#if defined(LORA_DIO1) && (LORA_DIO1 != RADIOLIB_NC)
gpio_wakeup_enable((gpio_num_t)LORA_DIO1, GPIO_INTR_HIGH_LEVEL); // SX126x/SX128x interrupt, active high
#endif
#ifdef RF95_IRQ
gpio_wakeup_enable((gpio_num_t)RF95_IRQ, GPIO_INTR_HIGH_LEVEL); // RF95 interrupt, active high
@@ -314,7 +344,8 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r
esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
#ifdef BUTTON_PIN
if (cause == ESP_SLEEP_WAKEUP_GPIO)
LOG_INFO("Exit light sleep gpio: btn=%d\n", !digitalRead(BUTTON_PIN));
LOG_INFO("Exit light sleep gpio: btn=%d\n",
!digitalRead(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN));
#endif
return cause;
@@ -337,6 +368,8 @@ void enableModemSleep()
esp32_config.max_freq_mhz = CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ;
#elif CONFIG_IDF_TARGET_ESP32S2
esp32_config.max_freq_mhz = CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ;
#elif CONFIG_IDF_TARGET_ESP32C3
esp32_config.max_freq_mhz = CONFIG_ESP32C3_DEFAULT_CPU_FREQ_MHZ;
#else
esp32_config.max_freq_mhz = CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ;
#endif

View File

@@ -4,7 +4,7 @@
#include "Observer.h"
#include "configuration.h"
void doDeepSleep(uint64_t msecToWake), cpuDeepSleep(uint64_t msecToWake);
void doDeepSleep(uint32_t msecToWake), cpuDeepSleep(uint32_t msecToWake);
#ifdef ARCH_ESP32
#include "esp_sleep.h"

View File

@@ -142,12 +142,14 @@ void XModemAdapter::handlePacket(meshtastic_XModem xmodemPacket)
case meshtastic_XModem_Control_EOT:
// End of transmission
sendControl(meshtastic_XModem_Control_ACK);
file.flush();
file.close();
isReceiving = false;
break;
case meshtastic_XModem_Control_CAN:
// Cancel transmission and remove file
sendControl(meshtastic_XModem_Control_ACK);
file.flush();
file.close();
FSCom.remove(filename);
isReceiving = false;

View File

@@ -0,0 +1,13 @@
[env:makerpython_nrf52840_sx1280_eink]
board_level = extra
extends = nrf52840_base
board = nordic_pca10059
build_flags = ${nrf52840_base.build_flags} -Ivariants/MakePython_nRF52840_eink -D PRIVATE_HW
-D PIN_EINK_EN
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/MakePython_nRF52840_eink>
lib_deps =
${nrf52840_base.lib_deps}
https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f
zinggjm/GxEPD2@^1.4.9
debug_tool = jlink
upload_port = /dev/ttyACM4

View File

@@ -0,0 +1,38 @@
/*
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
Copyright (c) 2016 Sandeep Mistry All right reserved.
Copyright (c) 2018, Adafruit Industries (adafruit.com)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "variant.h"
#include "nrf.h"
#include "wiring_constants.h"
#include "wiring_digital.h"
const uint32_t g_ADigitalPinMap[] = {
// P0
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
// P1
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47};
void initVariant()
{
// LED1 & LED2
pinMode(PIN_LED1, OUTPUT);
ledOff(PIN_LED1);
pinMode(PIN_LED2, OUTPUT);
ledOff(PIN_LED2);
}

View File

@@ -0,0 +1,159 @@
#ifndef _VARIANT_MAKERPYTHON_NRF82540_EINK_
#define _VARIANT_MAKERPYTHON_NRF82540_EINK_
#define MAKERPYTHON
/** Master clock frequency */
#define VARIANT_MCK (64000000ul)
#define USE_LFXO // Board uses 32khz crystal for LF
// define USE_LFRC // Board uses RC for LF
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include "WVariant.h"
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
// Number of pins defined in PinDescription array
#define PINS_COUNT (48)
#define NUM_DIGITAL_PINS (48)
#define NUM_ANALOG_INPUTS (6)
#define NUM_ANALOG_OUTPUTS (0)
#define RADIOLIB_GODMODE
// LEDs
#define PIN_LED1 (32 + 10) // LED P1.15
#define PIN_LED2 (-1) //
#define LED_BUILTIN PIN_LED1
#define LED_CONN PIN_LED2
#define LED_GREEN PIN_LED1
#define LED_BLUE PIN_LED2
#define LED_STATE_ON 0 // State when LED is litted
/*
* Buttons
*/
#define PIN_BUTTON1 (32 + 15) // P1.15 Built in button
/*
* Analog pins
*/
#define PIN_A0 (-1)
static const uint8_t A0 = PIN_A0;
#define ADC_RESOLUTION 14
// Other pins
#define PIN_AREF (-1) // AREF Not yet used
static const uint8_t AREF = PIN_AREF;
/*
* Serial interfaces
*/
#define PIN_SERIAL1_RX (-1)
#define PIN_SERIAL1_TX (-1)
// Connected to Jlink CDC
#define PIN_SERIAL2_RX (-1)
#define PIN_SERIAL2_TX (-1)
/*
* SPI Interfaces
*/
#define SPI_INTERFACES_COUNT 2
// here
//#define SPI_INTERFACES_COUNT 1
#define PIN_SPI_MISO (0 + 31) // MISO P0.31
#define PIN_SPI_MOSI (0 + 30) // MOSI P0.30
#define PIN_SPI_SCK (0 + 29) // SCK P0.29
// here
#define PIN_SPI1_MISO (-1) //
#define PIN_SPI1_MOSI (0 + 28) // EPD_MOSI P0.10
#define PIN_SPI1_SCK (0 + 2) // EPD_SCLK P0.09
static const uint8_t SS = (32 + 15); // LORA_CS P1.15
static const uint8_t MOSI = PIN_SPI_MOSI;
static const uint8_t MISO = PIN_SPI_MISO;
static const uint8_t SCK = PIN_SPI_SCK;
// here
/*
* eink display pins
*/
//#define PIN_EINK_EN (-1)
#define PIN_EINK_CS (0 + 3) // EPD_CS
#define PIN_EINK_BUSY (32 + 11) // EPD_BUSY
#define PIN_EINK_DC (32 + 13) // EPD_D/C
#define PIN_EINK_RES (-1) // Not used
#define PIN_EINK_SCLK (0 + 2) // EPD_SCLK
#define PIN_EINK_MOSI (0 + 28) // EPD_MOSI
#define USE_EINK
/*
* Wire Interfaces
*/
#define WIRE_INTERFACES_COUNT 1
#define PIN_WIRE_SDA (0 + 21) // SDA
#define PIN_WIRE_SCL (0 + 22) // SCL
// E-Byte E28 2.4 Ghz LoRa module
#define USE_SX1280
#define LORA_RESET (0 + 5)
#define SX128X_CS (0 + 23)
#define SX128X_DIO1 (0 + 4)
#define SX128X_BUSY (0 + 7)
//#define SX128X_TXEN (32 + 9)
//#define SX128X_RXEN (0 + 12)
#define SX128X_RESET LORA_RESET
#define PIN_GPS_EN (-1)
#define PIN_GPS_PPS (-1) // Pulse per second input from the GPS
#define GPS_RX_PIN PIN_SERIAL1_RX
#define GPS_TX_PIN PIN_SERIAL1_TX
// Battery
// The battery sense is hooked to pin A0 (5)
#define BATTERY_PIN PIN_A0
// and has 12 bit resolution
#define BATTERY_SENSE_RESOLUTION_BITS 12
#define BATTERY_SENSE_RESOLUTION 4096.0
// Definition of milliVolt per LSB => 3.0V ADC range and 12-bit ADC resolution = 3000mV/4096
#define VBAT_MV_PER_LSB (0.73242188F)
// Voltage divider value => 1.5M + 1M voltage divider on VBAT = (1.5M / (1M + 1.5M))
#define VBAT_DIVIDER (0.4F)
// Compensation factor for the VBAT divider
#define VBAT_DIVIDER_COMP (1.73)
// Fixed calculation of milliVolt from compensation value
#define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB)
#undef AREF_VOLTAGE
#define AREF_VOLTAGE 3.0
#define VBAT_AR_INTERNAL AR_INTERNAL_3_0
#define ADC_MULTIPLIER VBAT_DIVIDER_COMP // REAL_VBAT_MV_PER_LSB
#define VBAT_RAW_TO_SCALED(x) (REAL_VBAT_MV_PER_LSB * x)
#ifdef __cplusplus
}
#endif
/*----------------------------------------------------------------------------
* Arduino objects - C++ only
*----------------------------------------------------------------------------*/
#endif

View File

@@ -0,0 +1,10 @@
[env:makerpython_nrf52840_sx1280_oled]
board_level = extra
extends = nrf52840_base
board = nordic_pca10059
build_flags = ${nrf52840_base.build_flags} -Ivariants/MakePython_nRF52840_oled -D PRIVATE_HW
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/MakePython_nRF52840_oled>
lib_deps =
${nrf52840_base.lib_deps}
https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f
debug_tool = jlink

View File

@@ -0,0 +1,38 @@
/*
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
Copyright (c) 2016 Sandeep Mistry All right reserved.
Copyright (c) 2018, Adafruit Industries (adafruit.com)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "variant.h"
#include "nrf.h"
#include "wiring_constants.h"
#include "wiring_digital.h"
const uint32_t g_ADigitalPinMap[] = {
// P0
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
// P1
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47};
void initVariant()
{
// LED1 & LED2
pinMode(PIN_LED1, OUTPUT);
ledOff(PIN_LED1);
pinMode(PIN_LED2, OUTPUT);
ledOff(PIN_LED2);
}

View File

@@ -0,0 +1,137 @@
#ifndef _VARIANT_MAKERPYTHON_NRF82540_OLED_
#define _VARIANT_MAKERPYTHON_NRF82540_OLED_
#define MAKERPYTHON
/** Master clock frequency */
#define VARIANT_MCK (64000000ul)
#define USE_LFXO // Board uses 32khz crystal for LF
// define USE_LFRC // Board uses RC for LF
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include "WVariant.h"
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
// Number of pins defined in PinDescription array
#define PINS_COUNT (48)
#define NUM_DIGITAL_PINS (48)
#define NUM_ANALOG_INPUTS (6)
#define NUM_ANALOG_OUTPUTS (0)
#define RADIOLIB_GODMODE
// LEDs
#define PIN_LED1 (32 + 10) // LED P1.15
#define PIN_LED2 (-1) //
#define LED_BUILTIN PIN_LED1
#define LED_CONN PIN_LED2
#define LED_GREEN PIN_LED1
#define LED_BLUE PIN_LED2
#define LED_STATE_ON 0 // State when LED is litted
/*
* Buttons
*/
#define PIN_BUTTON1 (32 + 15) // P1.15 Built in button
/*
* Analog pins
*/
#define PIN_A0 (-1)
static const uint8_t A0 = PIN_A0;
#define ADC_RESOLUTION 14
// Other pins
#define PIN_AREF (-1) // AREF Not yet used
static const uint8_t AREF = PIN_AREF;
/*
* Serial interfaces
*/
#define PIN_SERIAL1_RX (-1)
#define PIN_SERIAL1_TX (-1)
// Connected to Jlink CDC
#define PIN_SERIAL2_RX (-1)
#define PIN_SERIAL2_TX (-1)
/*
* SPI Interfaces
*/
#define SPI_INTERFACES_COUNT 1
#define PIN_SPI_MISO (0 + 31) // MISO P0.31
#define PIN_SPI_MOSI (0 + 30) // MOSI P0.30
#define PIN_SPI_SCK (0 + 29) // SCK P0.29
static const uint8_t SS = (32 + 15); // LORA_CS P1.15
static const uint8_t MOSI = PIN_SPI_MOSI;
static const uint8_t MISO = PIN_SPI_MISO;
static const uint8_t SCK = PIN_SPI_SCK;
/*
* Wire Interfaces
*/
#define WIRE_INTERFACES_COUNT 1
#define PIN_WIRE_SDA (0 + 26) // SDA
#define PIN_WIRE_SCL (0 + 27) // SCL
// E-Byte E28 2.4 Ghz LoRa module
#define USE_SX1280
#define LORA_RESET (0 + 5)
#define SX128X_CS (0 + 23)
#define SX128X_DIO1 (0 + 4)
#define SX128X_BUSY (0 + 7)
//#define SX128X_TXEN (32 + 9)
//#define SX128X_RXEN (0 + 12)
#define SX128X_RESET LORA_RESET
#define PIN_GPS_EN (-1)
#define PIN_GPS_PPS (-1) // Pulse per second input from the GPS
#define GPS_RX_PIN PIN_SERIAL1_RX
#define GPS_TX_PIN PIN_SERIAL1_TX
// Battery
// The battery sense is hooked to pin A0 (5)
#define BATTERY_PIN PIN_A0
// and has 12 bit resolution
#define BATTERY_SENSE_RESOLUTION_BITS 12
#define BATTERY_SENSE_RESOLUTION 4096.0
// Definition of milliVolt per LSB => 3.0V ADC range and 12-bit ADC resolution = 3000mV/4096
#define VBAT_MV_PER_LSB (0.73242188F)
// Voltage divider value => 1.5M + 1M voltage divider on VBAT = (1.5M / (1M + 1.5M))
#define VBAT_DIVIDER (0.4F)
// Compensation factor for the VBAT divider
#define VBAT_DIVIDER_COMP (1.73)
// Fixed calculation of milliVolt from compensation value
#define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB)
#undef AREF_VOLTAGE
#define AREF_VOLTAGE 3.0
#define VBAT_AR_INTERNAL AR_INTERNAL_3_0
#define ADC_MULTIPLIER VBAT_DIVIDER_COMP // REAL_VBAT_MV_PER_LSB
#define VBAT_RAW_TO_SCALED(x) (REAL_VBAT_MV_PER_LSB * x)
#ifdef __cplusplus
}
#endif
/*----------------------------------------------------------------------------
* Arduino objects - C++ only
*----------------------------------------------------------------------------*/
#endif

View File

@@ -0,0 +1,14 @@
[env:ai-c3]
extends = esp32c3_base
board = esp32-c3-devkitm-1
board_level = extra
build_flags = ${esp32c3_base.build_flags}
-D PRIVATE_HW
-I variants/ai-c3
; as long as BSEC2 Software Library is not supported remove Sensors from build
build_src_filter = ${esp32c3_base.build_src_filter}
-<modules/Telemetry/EnvironmentTelemetry.cpp>
-<modules/Telemetry/AirQualityTelemetry.cpp>
-<modules/Telemetry/Sensor>
lib_ignore = ${esp32c3_base.lib_ignore}
BSEC Software Library

33
variants/ai-c3/variant.h Normal file
View File

@@ -0,0 +1,33 @@
#define HAS_TELEMETRY 0 // as long as BSEC2 is not supported
#define HAS_SENSOR 0 // as long as BSEC2 is not supported
#define SDA 0
#define SCL 1
#define I2C_SDA SDA
#define I2C_SCL SCL
#define BUTTON_PIN 9 // BOOT button
#define LED_PIN 30 // RGB LED
#define USE_RF95
#define RF95_SCK 4
#define RF95_MISO 5
#define RF95_MOSI 6
#define RF95_NSS 7
#define LORA_DIO0 10
#define LORA_DIO1 3
#define LORA_RESET 2
// WaveShare Core1262-868M
// https://www.waveshare.com/wiki/Core1262-868M
#define USE_SX1262
#define SX126X_CS RF95_NSS
#define SX126X_DIO1 LORA_DIO1
#define SX126X_BUSY 10
#define SX126X_RESET LORA_RESET
#define SX126X_E22 // use DIO2 as RF switch
#define HAS_GPS 0
#undef GPS_RX_PIN
#undef GPS_TX_PIN

View File

@@ -0,0 +1,37 @@
#ifndef Pins_Arduino_h
#define Pins_Arduino_h
#include <stdint.h>
#define USB_VID 0x303a
#define USB_PID 0x1001
#define EXTERNAL_NUM_INTERRUPTS 46
#define NUM_DIGITAL_PINS 48
#define NUM_ANALOG_INPUTS 20
#define analogInputToDigitalPin(p) (((p) < 20) ? (analogChannelToDigitalPin(p)) : -1)
#define digitalPinToInterrupt(p) (((p) < 48) ? (p) : -1)
#define digitalPinHasPWM(p) (p < 46)
static const uint8_t TX = 43;
static const uint8_t RX = 44;
// The default Wire will be mapped to PMU and RTC
static const uint8_t SDA = 12;
static const uint8_t SCL = 14;
// Default SPI will be mapped to Radio
static const uint8_t MISO = 39;
static const uint8_t SCK = 21;
static const uint8_t MOSI = 38;
static const uint8_t SS = 17;
//#define SPI_MOSI (11)
//#define SPI_SCK (14)
//#define SPI_MISO (2)
//#define SPI_CS (13)
//#define SDCARD_CS SPI_CS
#endif /* Pins_Arduino_h */

View File

@@ -0,0 +1,14 @@
[env:bpi_picow_esp32_s3]
extends = esp32s3_base
board = bpi_picow_esp32_s3
board_level = extra
;OpenOCD flash method
;upload_protocol = esp-builtin
;Normal method
upload_protocol = esptool
upload_port = /dev/ttyACM2
lib_deps =
${esp32_base.lib_deps}
caveman99/ESP32 Codec2@^1.0.1
build_flags =
${esp32_base.build_flags} -D PRIVATE_HW -I variants/bpi_picow_esp32_s3

View File

@@ -0,0 +1,73 @@
#define HAS_GPS 0
#undef GPS_RX_PIN
#undef GPS_TX_PIN
//#define HAS_SCREEN 0
//#define HAS_SDCARD
//#define SDCARD_USE_SPI1
#define USE_SSD1306
#define I2C_SDA 12
#define I2C_SCL 14
#define LED_PIN 46
#define LED_STATE_ON 0 // State when LED is litted
//#define BUTTON_PIN 15 // Pico OLED 1.3 User key 0 - removed User key 1 (17)
#define BUTTON_PIN 40
//#define BUTTON_PIN 0 // This is the BOOT button pad at the moment
//#define BUTTON_NEED_PULLUP
//#define USE_RF95 // RFM95/SX127x
#undef RF95_SCK
#undef RF95_MISO
#undef RF95_MOSI
#undef RF95_NSS
// WaveShare Core1262-868M OK
// https://www.waveshare.com/wiki/Core1262-868M
#define USE_SX1262
#ifdef USE_SX1262
#define RF95_MISO 39
#define RF95_SCK 21
#define RF95_MOSI 38
#define RF95_NSS 17
#define LORA_RESET 42
#define LORA_DIO1 5
#define LORA_BUSY 47
#define SX126X_CS RF95_NSS
#define SX126X_DIO1 LORA_DIO1
#define SX126X_BUSY LORA_BUSY
#define SX126X_RESET LORA_RESET
#define SX126X_E22
#endif
//#define USE_SX1280
#ifdef USE_SX1280
#define RF95_MISO 1
#define RF95_SCK 3
#define RF95_MOSI 4
#define RF95_NSS 2
#define LORA_RESET 17
#define LORA_DIO1 12
#define LORA_BUSY 47
#define SX128X_CS RF95_NSS
#define SX128X_DIO1 LORA_DIO1
#define SX128X_BUSY LORA_BUSY
#define SX128X_RESET LORA_RESET
#endif
//#define USE_EINK
/*
* eink display pins
*/
//#define PIN_EINK_CS
//#define PIN_EINK_BUSY
//#define PIN_EINK_DC
//#define PIN_EINK_RES (-1)
//#define PIN_EINK_SCLK 3
//#define PIN_EINK_MOSI 4

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