Compare commits

...
Author SHA1 Message Date
Thomas GöttgensandGitHub 9bd925226c Merge pull request #1759 from meshtastic/support-rak14004
support RAK14004 in Canned Messages
2022-10-06 16:37:25 +02:00
Thomas Göttgens e34ada3ff1 support RAK14004 in Canned Messages 2022-10-06 16:00:33 +02:00
Thomas GöttgensandGitHub 1ec1ff0773 Merge pull request #1758 from andrekir/PCF8563-lib
update PCF8563_Library to 1.0.0
2022-10-06 09:12:38 +02:00
Thomas GöttgensandGitHub 7f935717db Update platformio.ini 2022-10-06 08:56:02 +02:00
Thomas GöttgensandGitHub 5b1d3a0c51 Update platformio.ini 2022-10-06 08:55:58 +02:00
andrekir 484f340023 update PCF8563_Library to 1.0.0 2022-10-06 01:05:21 -03:00
Ben MeadorsandGitHub ab0cf025c5 Remove flag 2022-10-05 11:41:53 -05:00
Ben MeadorsandGitHub b384d9ea88 Remove yml exclusion for now 2022-10-05 11:18:37 -05:00
Ben MeadorsandGitHub bb2094c4de Fixed move 2022-10-05 11:11:14 -05:00
Ben MeadorsandGitHub 6708121ba6 Add factory erase uf2 to the release assets (#1756)
* Add factory erase uf2 to the release assets

* Copy single file

* Overwrite hopefully
2022-10-05 10:52:51 -05:00
Thomas GöttgensandGitHub 46a9bb3f7d Merge pull request #1755 from meshtastic/gps-rollup
GPS Rollup, incorporates changes from @pmarches and @lewisxhe
2022-10-05 15:32:27 +02:00
Thomas Göttgens 62498d0935 GPS Rollup, incorporates changes from @pmarches and @lewisxhe 2022-10-05 14:59:07 +02:00
Thomas GöttgensandGitHub c70184fbed Merge pull request #1754 from meshtastic/issue-1707
wire in part 2 of serial mode - implements #1228
2022-10-05 13:45:11 +02:00
Thomas Göttgens 4d2cb45f9f wire in part 1 of serial mode... select if you want textmsg or own portnum via config. 2022-10-05 11:39:50 +02:00
Thomas GöttgensandGitHub e5605cc6fe Merge pull request #1753 from meshtastic/bug-1713
fix #1713
2022-10-05 10:51:56 +02:00
Thomas Göttgens f7331a2e41 fix #1713
stop output to serial debug after config has been loaded (if serial is disabled), and only accept protobuf packets from that point on.
2022-10-05 10:33:39 +02:00
Thomas GöttgensandGitHub 838271a14f Merge pull request #1751 from rjmcdougall/radiolib-5.4.0-fix
Switch to 5.4.0 using latest fix (170ce9) to error check after calibr…
2022-10-05 09:25:05 +02:00
Thomas GöttgensandGitHub b6b23907ed Merge pull request #1752 from meshtastic/flash-save
Flash saver
2022-10-05 09:12:11 +02:00
Thomas GöttgensandGitHub b240b9a088 Use the global radiolib... 2022-10-05 09:02:46 +02:00
Thomas GöttgensandGitHub b3a484f1e5 update to Radiolib 5.4.1 2022-10-05 09:01:39 +02:00
Thomas GöttgensandGitHub f3042ddf37 Update NodeDB.cpp 2022-10-05 08:56:00 +02:00
Thomas Göttgens 54816231e9 Calculate CRC32 of Protobuf and compare before save. 2022-10-05 08:52:27 +02:00
Richard McDougall 1c168d7d62 Switch to 5.4.0 using latest fix (170ce9) to error check after calibration 2022-10-04 10:52:23 -07:00
Thomas Göttgens 063c4904ff only save files when they changed - also clamp app version 2022-10-04 17:25:03 +02:00
Thomas Göttgens fefcbb147b fix #1646 2022-10-04 15:27:18 +02:00
Thomas Göttgens 53d48e8f61 use radiolib 5.3 for now 2022-10-04 15:19:00 +02:00
Thomas GöttgensandGitHub ce5bce5cdc Merge pull request #1749 from meshtastic/flash-save
Only save the changed parts of config to disk.
2022-10-04 14:52:10 +02:00
Thomas Göttgens 3597685b23 Only save the changed parts of config to disk. 2022-10-04 14:32:07 +02:00
Thomas GöttgensandGitHub dc097c7230 Merge pull request #1729 from rjmcdougall/pcf8563rtc
Adjust year, hour, minute for PCF8563
2022-10-04 13:40:40 +02:00
Thomas GöttgensandGitHub b148781e4b Missed one. 2022-10-04 13:29:06 +02:00
Thomas GöttgensandGitHub 5d8826e8ef Merge branch 'master' into pcf8563rtc 2022-10-04 13:27:49 +02:00
Thomas GöttgensandGitHub 39a51c7fbb update lib to make this work 2022-10-04 13:26:20 +02:00
Thomas GöttgensandGitHub 129edde338 Merge pull request #1746 from meshtastic/feature-1406
implement #1406
2022-10-04 10:01:19 +02:00
Thomas Göttgens 93cc278eee implement #1406 2022-10-04 09:47:54 +02:00
Thomas GöttgensandGitHub c34198264a Merge branch 'master' into pcf8563rtc 2022-10-04 09:38:33 +02:00
Thomas GöttgensandGitHub 054b12325d Merge pull request #1745 from meshtastic/compiler-warning
fix compiler warning
2022-10-04 09:27:34 +02:00
Thomas Göttgens 0f7a126828 fix compiler warning 2022-10-04 09:11:24 +02:00
Thomas GöttgensandGitHub 7ff72fb981 Merge pull request #1744 from meshtastic/dependency-scan
add versioning to all lib depends
2022-10-04 09:10:28 +02:00
Thomas Göttgens 0fe99595a9 Lib update and fix include errors 2022-10-04 08:59:03 +02:00
Thomas Göttgens b2ff628cec add versioning to all lib depends (compatible upgrade allowed) and move as many as possible off github and into PIO registry.
Also add a script to check for lib updates (maybe in CI?)
2022-10-04 08:40:39 +02:00
Thomas GöttgensandGitHub 86a3bd6db8 Merge pull request #1742 from meshtastic/bug-1740
Clean up GPS code and add some flags per #1740
2022-10-04 08:38:57 +02:00
Thomas GöttgensandGitHub 73a5357d0e Brainfart. This is already km/h 2022-10-04 08:11:07 +02:00
Richard McDougallandGitHub 2faf507c0d Merge branch 'meshtastic:master' into pcf8563rtc 2022-10-03 13:55:49 -07:00
Thomas Göttgens cf124d97b8 Clean up GPS code and add some flags per #1740 2022-10-03 20:30:11 +02:00
Sacha WeatherstoneandGitHub 482c0766af Merge pull request #1741 from andrekir/channel_num
move channel_num to loraConfig
2022-10-03 16:34:42 +10:00
Ben MeadorsandGitHub 7e5a26fde5 Merge branch 'master' into channel_num 2022-10-02 19:45:32 -05:00
Ben Meadors e85af2f732 regen protos 2022-10-02 19:45:15 -05:00
Sacha WeatherstoneandGitHub 4df81008bc Merge branch 'master' into channel_num 2022-10-03 10:32:56 +10:00
Ben MeadorsandGitHub 803dc69ccd Update radiolib 2022-10-02 09:48:48 -05:00
Thomas GöttgensandGitHub 42308cca5b Merge branch 'master' into pcf8563rtc 2022-10-01 17:31:02 +02:00
Thomas GöttgensandGitHub ea991a4eee Merge pull request #1737 from GUVWAF/EnhancedSimRadio
Let SimRadio communicate via TCP
2022-10-01 17:24:26 +02:00
GUVWAF 04db2d4410 Merge branch 'EnhancedSimRadio' of https://github.com/GUVWAF/Meshtastic-device into EnhancedSimRadio 2022-10-01 17:07:59 +02:00
GUVWAF 076c1ed2ee Merge branch 'EnhancedSimRadio' of https://github.com/GUVWAF/Meshtastic-device into EnhancedSimRadio 2022-10-01 17:05:49 +02:00
Thomas GöttgensandGitHub 75aa4ea325 suppress cppcheck warning 2022-10-01 17:05:04 +02:00
GUVWAF e54be07dc0 Update include path in MeshService 2022-10-01 17:04:19 +02:00
GUVWAF d439d00e25 Move SimRadio to platform/portduino 2022-10-01 17:03:40 +02:00
GUVWAF c4bea793af Mark WifiServerPort constructor as explicit 2022-10-01 17:02:16 +02:00
GUVWAF b53dcb932e Adapt conditional include 2022-10-01 17:01:25 +02:00
Thomas GöttgensandGitHub 371428d6ab Fix compile error on nRF52 2022-10-01 16:41:49 +02:00
Thomas GöttgensandGitHub 1970d0c00f Merge branch 'master' into EnhancedSimRadio 2022-10-01 15:59:44 +02:00
1dd7aa935f [create-pull-request] automated change (#1738)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2022-10-01 08:47:35 -05:00
Thomas GöttgensandGitHub 6b40f9d95c Unfork this lib, we're done here now. 2022-10-01 15:27:13 +02:00
Thomas GöttgensandGitHub b3717d0396 Merge branch 'master' into pcf8563rtc 2022-10-01 15:20:16 +02:00
82ba95833b strcmp returns zero if strings are equal (#1736)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2022-10-01 08:18:25 -05:00
Thomas GöttgensandGitHub 28384df702 Merge pull request #1734 from meshtastic/Build-Image
Build image
2022-10-01 15:17:41 +02:00
GUVWAF aee06f4738 Suppress debug messages in PhoneAPI as they flood the logs when a TCP connection is open 2022-10-01 12:09:43 +02:00
GUVWAF ab282765d4 Let SimRadio start receive a packet if its PortNum is Simulator_App 2022-10-01 12:06:59 +02:00
GUVWAF 5d464badc8 Give TCP port as argument to API server 2022-10-01 12:05:20 +02:00
GUVWAF 68282682de Use new SimRadio in main for Portduino 2022-10-01 12:03:35 +02:00
GUVWAF 2696b04138 Allow Portduino to set the TCP port 2022-10-01 12:02:29 +02:00
GUVWAF 31dc37150b Fix typo 2022-10-01 12:00:31 +02:00
GUVWAF e66d9d0add Add content to SimRadio, similar to RadioInterface 2022-10-01 11:59:20 +02:00
GUVWAF 067bde321b Remove old SimRadio from RadioInterface 2022-10-01 11:57:27 +02:00
GUVWAF 84ec364ac2 Add enhanced SimRadio files 2022-10-01 11:56:16 +02:00
Thomas GöttgensandGitHub 32990856e3 Merge branch 'master' into Build-Image 2022-10-01 10:31:59 +02:00
Thomas GöttgensandGitHub a1bd5c9ea0 Accomodate for new flash files 2022-10-01 10:31:25 +02:00
Thomas Göttgens 51f0e7879a use the right firmware artefact 2022-10-01 10:06:13 +02:00
Thomas Göttgens 0bdb90d133 remove hard to maintain system-info bootloader 2022-10-01 09:50:16 +02:00
Thomas Göttgens e98c11ff89 The new combined firmware starts flashing at offset 0, no need to flash system-info or partitions any more. 2022-10-01 09:46:56 +02:00
andrekir 8f84d7089c move channel_num to loraConfig 2022-09-30 17:33:43 -03:00
Thomas Göttgens b0712c4186 make other platforms happy again 2022-09-29 21:23:01 +02:00
Thomas Göttgens 8f92383ce4 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-09-29 17:05:11 +02:00
Thomas Göttgens c571fc9e24 generate a monolithic flash image for the app. 2022-09-29 17:04:56 +02:00
Thomas GöttgensandGitHub 05126bc6dc Merge branch 'master' into pcf8563rtc 2022-09-29 16:33:43 +02:00
Thomas GöttgensandGitHub de56a370c6 Merge pull request #1733 from meshtastic/TLORA-fix
Tlora fix
2022-09-29 13:37:51 +02:00
Thomas Göttgens daf189bf4b Check in variant.h change 2022-09-29 13:23:23 +02:00
Thomas Göttgens d95ec7e6b9 fix TLORA-V2.1-1.6 2022-09-29 13:21:48 +02:00
Ben MeadorsandGitHub ac235bcabb Reset nodedb wiring (#1724) 2022-09-28 16:47:26 -05:00
Neil HaoandGitHub ab4b3a50ee 'battery_gauge_fix' (#1731) 2022-09-28 15:53:26 -05:00
Thomas Göttgens 7f0fb2a2b6 Move file to right spot in source tree 2022-09-28 20:13:41 +02:00
Richard McDougall ade1edfdfc Adjust year, hour, minute for PCF8563 2022-09-27 22:51:40 -07:00
Thomas GöttgensandGitHub 4723faa95f Merge pull request #1728 from meshtastic/bug-1669
fixes #1669
2022-09-27 14:15:38 +02:00
Thomas GöttgensandGitHub 93f83b0fcb Merge branch 'master' into bug-1669 2022-09-27 14:03:48 +02:00
Thomas Göttgens 8f84f7c0a5 fixes #1669 2022-09-27 14:03:02 +02:00
Ben MeadorsandGitHub 48e4101f1c Move it 2022-09-27 06:08:24 -05:00
Thomas GöttgensandGitHub e6bb79f4c1 Merge pull request #1727 from meshtastic/ESPIDF-Littlefs
use the native littlefs builder of newer framework
2022-09-27 00:50:41 +02:00
Thomas GöttgensandGitHub 0bef3464f5 Merge branch 'master' into ESPIDF-Littlefs 2022-09-27 00:50:33 +02:00
Thomas GöttgensandGitHub 3c038a8c50 Update main_matrix.yml 2022-09-27 00:50:16 +02:00
Thomas GöttgensandGitHub b8eb751316 Update build-esp32.sh 2022-09-27 00:23:50 +02:00
Thomas GöttgensandGitHub 5332db1eca Include OTA Firmware in Build 2022-09-27 00:21:45 +02:00
Thomas GöttgensandGitHub 9deda962aa Merge branch 'master' into ESPIDF-Littlefs 2022-09-27 00:16:41 +02:00
Thomas Göttgens c53434539b use the native littlefs builder of newer framework 2022-09-27 00:16:12 +02:00
Ben MeadorsandGitHub 7f179deaf3 Update build-esp32.sh 2022-09-26 16:01:28 -05:00
Ben MeadorsandGitHub da29fa139f Copy the current one 2022-09-26 16:00:20 -05:00
Thomas GöttgensandGitHub 1d8a562fd9 Merge pull request #1725 from meshtastic/AsyncOTA
Changes for OTA Support on ESP32
2022-09-26 22:57:48 +02:00
Thomas GöttgensandGitHub 0dbf97afab Merge branch 'master' into AsyncOTA 2022-09-26 22:57:23 +02:00
Thomas GöttgensandGitHub e5720fba3e Merge pull request #1726 from meshtastic/partitions
Include partitions.bin
2022-09-26 22:56:59 +02:00
Ben MeadorsandGitHub 498ac00b92 Copy cpartitions.bin 2022-09-26 15:51:09 -05:00
Ben MeadorsandGitHub 226a2dfe04 Include partitions.bin 2022-09-26 15:48:02 -05:00
Thomas Göttgens 7e9a233296 - new Bootloader for ESP-IDF 4.2
- save partition table to device
- modify partition table for async OTA
2022-09-26 22:42:58 +02:00
Ben MeadorsandGitHub ae311c838e Try to decode mqtt packets first (#1705)
* Try to decode first

* Remove GPS pins from TLoRAv1 so that it can boot

* Use release version of radio lib

* Use fixed versions of esp framework and tool chain
2022-09-25 09:39:50 -05:00
Thomas Göttgens de769db3bc Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-09-23 23:29:52 +02:00
Thomas Göttgens 5fa96c7fd1 missed one, sorry 2022-09-23 23:29:32 +02:00
Thomas GöttgensandGitHub 2ee0c9a67a Merge pull request #1720 from meshtastic/axe-framerate-debug
get rid of framerate debug messages
2022-09-23 23:21:21 +02:00
Thomas Göttgens 347af0210e Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-09-23 23:09:20 +02:00
Thomas GöttgensandGitHub d8455d687c Merge branch 'master' into axe-framerate-debug 2022-09-23 23:08:46 +02:00
Thomas Göttgens 34fef4c4e7 get rid of framerate debug messages 2022-09-23 23:07:26 +02:00
Thomas GöttgensandGitHub 18bb373219 switch Bluetooth back on when wifi is disabled and bluetooth is enabled. This still had the old behaviour to check for a set ssid... (#1719) 2022-09-23 15:10:33 -05:00
Thomas GöttgensandGitHub 2f74f9ca15 Merge pull request #1718 from meshtastic/ESPIDF-Rollup
Suppress compiler warning
2022-09-23 21:33:37 +02:00
Thomas GöttgensandGitHub 5775c390f3 Merge branch 'master' into ESPIDF-Rollup 2022-09-23 21:19:19 +02:00
Thomas GöttgensandGitHub 80826b8712 Merge pull request #1711 from meshtastic/ESPIDF-Littlefs
Filesystem fixes for LittleFS
2022-09-23 21:14:40 +02:00
Thomas GöttgensandGitHub 664d18cf58 t'ell that came from? 2022-09-23 21:03:53 +02:00
Thomas Göttgens bc2cddcb11 Filesystem abstraction would work really well, if it wasn't for crap vendor toolchains. 2022-09-23 20:43:42 +02:00
Thomas Göttgens 4949bda606 Don't delete OEM.proto on factory reset 2022-09-23 19:52:42 +02:00
Thomas Göttgens b4f75ad042 use exception decoder 2022-09-23 19:52:07 +02:00
Thomas Göttgens af4d11e17b fix and refactor FSCommon for new ESPIDF 2022-09-23 19:51:08 +02:00
Thomas GöttgensandGitHub e8f4a8b739 Merge branch 'master' into ESPIDF-Littlefs 2022-09-23 18:45:37 +02:00
Thomas Göttgens fae6693f8f fix (or better suppress) another compiler warning 2022-09-23 12:37:59 +02:00
Thomas Göttgens 0646ecdec4 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-09-23 12:32:07 +02:00
Thomas GöttgensandGitHub 544c89460f Nullify older saved proto files once more
this will be neccessary for the 1.3.42 release, since we renumbered some protos again. Subsequent additions to protos don't need this, just when we reshuffle.
2022-09-23 12:28:32 +02:00
Thomas Göttgens 15089f5b01 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-09-23 09:55:00 +02:00
Ben MeadorsandGitHub 8ef510035d Owner reboot (#1716) 2022-09-22 08:02:58 -05:00
Sacha WeatherstoneandGitHub 864b1f754c Merge branch 'master' into ESPIDF-Littlefs 2022-09-22 14:58:53 +10:00
Sacha WeatherstoneandGitHub 883a2ebac0 Merge pull request #1717 from ajmcquilkin/ajmcquilkin/imperial-screen-units
Add Support for Imperial Units on Screen
2022-09-22 13:22:22 +10:00
Adam McQuilkin bbe5b2e42c Remove accidental whitespace changes 2022-09-21 22:48:12 -04:00
Adam McQuilkin 1b316b111f Initial commit 2022-09-21 22:37:36 -04:00
Thomas Göttgens d0720620e8 fix compiler warning 2022-09-21 17:22:31 +02:00
Thomas Göttgens cf4947d898 Fix build for non-ESP32 2022-09-21 17:05:10 +02:00
Thomas Göttgens b5a8efa16b Filesystem fixes for LittleFS 2022-09-21 16:47:10 +02:00
Thomas GöttgensandGitHub b38ae783b9 Merge pull request #1706 from meshtastic/communicator
Freetext Input with CardKB
2022-09-21 16:33:49 +02:00
Thomas GöttgensandGitHub cbd8346c93 Merge branch 'master' into communicator 2022-09-21 16:10:28 +02:00
Thomas GöttgensandGitHub c0bfb979fd Merge pull request #1710 from meshtastic/serial-flush
Fix Serial comms with new framework
2022-09-21 16:01:01 +02:00
Thomas GöttgensandGitHub 7c5a36ce38 Update SerialConsole.cpp 2022-09-21 15:46:56 +02:00
Thomas GöttgensandGitHub fc729b0cbb Send PROTOBUF over serial without delay 2022-09-21 15:36:17 +02:00
Thomas GöttgensandGitHub 0b81a25fda Output serial console data without buffering 2022-09-21 15:34:48 +02:00
Thomas Göttgens 011db443ba Bugfixes in Freetext Module.
- work without fixed messages defined
- honour cursor position on backspace
- don't send an empty string
- compiler warnings in font engine fixed
2022-09-21 10:42:10 +02:00
Thomas Göttgens b73e240f4d relative paths are relative 2022-09-20 16:36:50 +02:00
Thomas Göttgens 6de77ee310 use cyrillic font if defined 2022-09-20 16:30:21 +02:00
Thomas Göttgens 0a8293a2d6 Cursor editing 2022-09-20 16:21:32 +02:00
Thomas Göttgens d0ad5dd4cf - don't swallow keystrokes
- switch back and forth between the 2 modes.
2022-09-20 14:28:42 +02:00
Thomas Göttgens ab342ce904 Freetext Input with CardKB Take 1 - Also removes FacesKB support, this thing is ancient. 2022-09-20 13:50:18 +02:00
Thomas GöttgensandGitHub 140250ef03 Merge pull request #1704 from meshtastic/ESPIDF-Rollup
ESP and TFT misc fixes
2022-09-19 17:57:12 +02:00
Thomas Göttgens ed90275370 use double buffering on TFT screens 2022-09-19 16:57:18 +02:00
Thomas Göttgens e8b28faaf1 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-09-19 16:18:16 +02:00
Thomas Göttgens afcc7b6a56 Always use the latest framework for ESP32 2022-09-19 16:18:01 +02:00
Thomas GöttgensandGitHub e27a507a28 Merge pull request #1703 from meshtastic/ESPIDF-Rollup
Small fixes for ESP Serial Init and Power FSM debug garble.
2022-09-19 15:57:47 +02:00
Thomas GöttgensandGitHub 207f701f0a Update GPS.cpp 2022-09-19 15:46:59 +02:00
Thomas Göttgens dd8cb1c7fb Small fixes for ESP Serial Init and Power FSM debug garble. 2022-09-19 15:36:48 +02:00
Thomas GöttgensandGitHub ccf93b8c23 Merge pull request #1687 from meshtastic/ESPIDF-Rollup
use the new ESP Framework for our older boards too
2022-09-19 12:18:09 +02:00
Thomas Göttgens 4c6f3ead60 fixing I2C requests and Wifi Power Saving Modes. 2022-09-19 12:05:57 +02:00
Thomas GöttgensandGitHub 2d81d359b8 Update esp32.ini
Update arch by hand
2022-09-19 09:36:13 +02:00
Thomas GöttgensandGitHub 1f96d5d957 Merge branch 'master' into ESPIDF-Rollup 2022-09-19 09:33:50 +02:00
Thomas GöttgensandGitHub 033f45d4da Merge pull request #1702 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-09-19 09:32:01 +02:00
thebenternandGitHub ae2c514ee7 [create-pull-request] automated change 2022-09-18 20:55:27 +00:00
Andre KandGitHub 80ddb81fac fix yet another typo 2022-09-18 17:31:59 -03:00
Andre KandGitHub 4bc29200be fix default channel names (#1701) 2022-09-18 09:41:27 -05:00
Ben MeadorsandGitHub 55c55fb705 pip versions back in order 2022-09-17 20:03:11 -05:00
Ben MeadorsandGitHub 0e2ab75bb0 Set tx_enabled upon initial region assignment (#1700) 2022-09-17 14:49:09 -05:00
Ben MeadorsandGitHub 128d20b290 tx_enabled fix (#1699)
* Defaults

* Print
2022-09-17 12:18:32 -05:00
Ben Meadors ad9cc40b97 Increasebaud for local except for RAK11200 2022-09-17 08:25:40 -05:00
Ben MeadorsandGitHub e0d3ac01b0 Merge branch 'master' into ESPIDF-Rollup 2022-09-17 08:22:44 -05:00
Ben MeadorsandGitHub 0f87adad7b Power state lies and other fixes (#1698)
* Power interval defaults and factory reset

* Ternary

* Fixes
2022-09-16 11:00:05 -05:00
9481461145 Add GNSS model recognition functio (#1696)
* Add GNSS model recognition function

* Fix GNSS initialization failure

* GPS.cpp difference between runOnce and ESP32S3 and ESP32 versions

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2022-09-15 13:43:04 -05:00
Ben MeadorsandGitHub accd23eddc Factory reset on device state expired (#1695) 2022-09-15 12:15:16 -05:00
Thomas GöttgensandGitHub 7c202b6069 Merge branch 'master' into ESPIDF-Rollup 2022-09-13 19:18:20 +02:00
Thomas GöttgensandGitHub e93b98ff98 Merge pull request #1694 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-09-13 14:32:29 +02:00
caveman99andGitHub b1ac2cf821 [create-pull-request] automated change 2022-09-13 12:31:51 +00:00
Ben MeadorsandGitHub bfd1fecc2a Merge branch 'master' into ESPIDF-Rollup 2022-09-13 06:36:56 -05:00
Ben MeadorsandGitHub c622a9b4be Update python temp hack 2022-09-12 20:21:19 -05:00
Ben MeadorsandGitHub ade66cd8f4 Merge branch 'master' into ESPIDF-Rollup 2022-09-12 18:07:42 -05:00
Ben MeadorsandGitHub 397030b5a6 GPS intervals (#1693)
* GPS intervals

* Backwards logic

* Oops
2022-09-12 18:07:21 -05:00
Ben MeadorsandGitHub adc50f40b1 Merge branch 'master' into ESPIDF-Rollup 2022-09-12 14:56:09 -05:00
Ben MeadorsandGitHub 32d92d9b75 Qualify tbeam filesystem bins 2022-09-12 14:30:54 -05:00
Ben Meadors 18f37981bb Spelling and fixing defaults 2022-09-12 07:55:17 -05:00
Ben Meadors a8711bc54a Add tbeam-s3-core 2022-09-12 07:39:41 -05:00
Thomas Göttgens eac2613743 make platformio.ini even more modular 2022-09-12 14:02:21 +02:00
Thomas Göttgens 4a0c18c4cd Merge branch 'ESPIDF-Rollup' of github.com:meshtastic/Meshtastic-device 2022-09-12 13:40:52 +02:00
Thomas Göttgens e376a3a28e just use the general toolkit 2022-09-12 13:40:20 +02:00
Thomas Göttgens a6bdff53c9 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-09-12 13:25:54 +02:00
Thomas GöttgensandGitHub b5c5483ced Merge branch 'master' into ESPIDF-Rollup 2022-09-12 12:50:38 +02:00
Thomas GöttgensandGitHub 601422e92b Merge pull request #1692 from meshtastic/caveman99-1542
implement #1542
2022-09-12 11:05:07 +02:00
Thomas Göttgens dbbe5e59ae Merge branch 'caveman99-1542' of github.com:meshtastic/Meshtastic-device 2022-09-12 10:54:09 +02:00
Thomas Göttgens b96dd6d36d T-Echo does not have Serial2 2022-09-12 10:53:11 +02:00
Thomas GöttgensandGitHub e6b6e175b8 Merge branch 'master' into caveman99-1542 2022-09-12 10:10:08 +02:00
Thomas Göttgens 2ff549d458 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-09-12 10:09:24 +02:00
Thomas GöttgensandGitHub a1230500fd Merge pull request #1691 from meshtastic/proto-fix
Reinstate GPS Flag
2022-09-12 10:09:07 +02:00
Thomas Göttgens 17db87e042 implement #1542 2022-09-12 10:08:32 +02:00
Thomas Göttgens 42d2986cb8 Reinstate GPS Flag 2022-09-12 09:37:21 +02:00
Thomas Göttgens cc054a13e2 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-09-12 09:25:04 +02:00
60b4dbfdcd More default inits. (#1689)
* More default inits.

* update protobufs

* Try checking has_device first

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2022-09-11 08:36:47 -05:00
Sacha WeatherstoneandGitHub c446a0f222 Merge branch 'master' into ESPIDF-Rollup 2022-09-11 10:45:27 +10:00
Ben Meadors f98e96cf1b Slots for upcoming telemetry sensor support 2022-09-10 17:28:01 -05:00
Thomas GöttgensandGitHub 3102777a71 Update platformio.ini 2022-09-10 20:53:23 +02:00
Thomas GöttgensandGitHub ed95f382cf Merge branch 'master' into ESPIDF-Rollup 2022-09-10 20:39:54 +02:00
Ben MeadorsandGitHub 7f18c0fb77 Init default intervals (#1688)
* Init default intervals

* Spacing

* move isrouter check

* Line break

* Oops
2022-09-10 12:35:36 -05:00
Sacha WeatherstoneandGitHub 52e4f93760 Merge branch 'master' into ESPIDF-Rollup 2022-09-10 22:13:56 +10:00
Sacha WeatherstoneandGitHub 0167304300 Merge pull request #1656 from meshtastic/pref_defaults
Set `config.lora.hop_limit` to `HOP_RELIABLE`
2022-09-10 18:24:27 +10:00
Sacha WeatherstoneandGitHub 7aaca3d486 Merge branch 'master' into pref_defaults 2022-09-10 18:11:16 +10:00
Thomas Göttgens bf3306fbc8 use the new ESP Framework for our older boards too 2022-09-09 22:31:30 +02:00
Thomas GöttgensandGitHub e375a8460b Merge pull request #1676 from lewisxhe/master
Add tbeam esp32s3 version support, replace AXP202X_Library with XPowersLib.
2022-09-09 22:01:20 +02:00
Thomas GöttgensandGitHub ff88900982 wrong name for constant in merge 2022-09-09 21:49:54 +02:00
Thomas GöttgensandGitHub 7f293bfda3 Merge branch 'master' into master 2022-09-09 21:39:29 +02:00
Ben MeadorsandGitHub 99de0a76a5 Temporary hack (undo after 1.3.41 release) 2022-09-09 13:54:03 -05:00
Ben MeadorsandGitHub 47ffb9c70d Make a change to trigger CI (#1686) 2022-09-09 13:41:01 -05:00
Thomas GöttgensandGitHub 1231f926ea Merge pull request #1684 from meshtastic/proto-shakeup
Adapt to new protobufs - TODO: factory_reset rewire
2022-09-09 13:26:59 +02:00
Thomas Göttgens e05e888fca Update admin config field 2022-09-09 13:14:15 +02:00
Thomas Göttgens 03580f5be8 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-09-09 13:11:23 +02:00
Thomas GöttgensandGitHub 90dabfea30 Merge pull request #1685 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-09-09 13:11:01 +02:00
caveman99andGitHub c8d7b1aba0 [create-pull-request] automated change 2022-09-09 11:10:31 +00:00
Thomas Göttgens 6065ef3a54 catch renamed targets 2022-09-09 13:04:37 +02:00
Thomas Göttgens 86c7eefc91 add missing files 2022-09-09 12:55:31 +02:00
Thomas Göttgens f7b12f0695 Adapt to new protobufs - TODO: factory_reset rewire 2022-09-09 12:51:41 +02:00
Thomas GöttgensandGitHub 0c46ad91ef Merge pull request #1683 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-09-09 12:04:43 +02:00
caveman99andGitHub 96cab75ccd [create-pull-request] automated change 2022-09-09 10:04:11 +00:00
Thomas GöttgensandGitHub a7138b7213 Merge pull request #1682 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-09-09 11:20:51 +02:00
caveman99andGitHub 11590e33d3 [create-pull-request] automated change 2022-09-09 09:19:18 +00:00
lewishe a3a92d2d13 Remove unnecessary edits 2022-09-08 10:54:33 +08:00
lewishe 2088036521 Differentiate t-beam-s3 GNSS from t-echo 2022-09-08 10:52:03 +08:00
lewishe 7d0e16d1b6 Add some explanations about PMU and prevent null pointer judgment 2022-09-08 10:45:12 +08:00
lewishe 35c77ef99c Simplify HAS_PMU macro definition 2022-09-08 10:36:53 +08:00
lewishe 9244d03cf9 Rename axp192_found to pmu_found to avoid confusion 2022-09-08 10:32:12 +08:00
lewishe a50a461675 Change mesh.pd.h t-beam-s3-core index to 12 2022-09-08 10:28:53 +08:00
Thomas GöttgensandGitHub f78911666e Merge branch 'master' into master 2022-09-07 20:25:38 +02:00
f1e6585726 [create-pull-request] automated change (#1678)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2022-09-07 09:18:37 -05:00
lewishe b8f862ac46 Merge remote-tracking branch 'origin/master' 2022-09-07 09:48:39 +08:00
Ben MeadorsandGitHub 94a572aee6 Merge branch 'master' into pref_defaults 2022-09-06 20:25:20 -05:00
Ben MeadorsandGitHub e87ecc210a Wifi enabled plumbed in (#1677)
* Wifi enabled

* Wifi requires reboot

* Increment DEVICESTATE_CUR_VER
2022-09-06 14:06:44 -05:00
lewis heandGitHub a9e7a33473 Merge branch 'master' into master 2022-09-06 18:53:22 +08:00
lewishe 5621719eef Add tbeam esp32s3 version support, replace AXP202X_Library with XPowersLIb 2022-09-06 15:58:33 +08:00
cb3010b58c OLED Cyrillic Support for v1.3 (#1640)
* Extended ASCII codes and cyrillic support

(cherry picked from commit e977840805)

* Fixed `ё`, `Ё` letters

(cherry picked from commit 2f4a2ccb2f)

* Fixed `customFontTableLookup` execution flow

(cherry picked from commit 377f909f36)

* [OLED] Specifying the language by defining it in `platformio.ini`

(cherry picked from commit ddd8132b24)

* [OLED] localization guide

(cherry picked from commit a3267c886f)

* [OLED] Cyrillic support

Localization guide has been moved to https://github.com/meshtastic/Meshtastic/tree/master/docs/developers/Firmware

https://meshtastic.org/docs/developers/Firmware/oled-l10n-guide

Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2022-09-04 15:00:10 -05:00
Ben MeadorsandGitHub a27a07956f Merge branch 'master' into pref_defaults 2022-09-03 22:10:37 -05:00
Ben MeadorsandGitHub 285ba9639e Fix screen on secs (#1673)
* Fix screen on secs

* getIntervalOrDefaultMs

* Display correction

* Paren
2022-09-03 22:10:11 -05:00
Ben MeadorsandGitHub f54f60c31c Merge branch 'master' into pref_defaults 2022-09-03 14:06:27 -05:00
Ben MeadorsandGitHub 84e438f72f Mqtt json_enabled (#1672)
* Payload variants

* Waypoints and fixes

* Remove json send to mesh. I think protobuf messages already do that

* whoops

* Added json_enabled mqtt config
2022-09-03 14:06:10 -05:00
lewis f767fd5075 Modified to be compatible with the new version of sdk, compatible with esp32s3 2022-09-03 23:38:40 +08:00
lewis heandGitHub 8fb8212434 i2cScan probe adds another ssd1306 subclass new to output logs correctly (#1671) 2022-09-03 07:26:49 -05:00
lewis 8d5ffb7262 i2cScan probe adds another ssd1306 subclass new to output logs correctly 2022-09-03 16:44:32 +08:00
Neil HaoandGitHub 70e1a208d5 'snow_screen_hotfix' (#1670) 2022-09-02 19:43:33 -05:00
Ben MeadorsandGitHub 9d3cac7cdb MQTT Json Payload variants (#1667)
* Payload variants

* Waypoints and fixes

* Remove json send to mesh. I think protobuf messages already do that

* whoops
2022-09-01 17:54:24 -05:00
Ben MeadorsandGitHub 84f1edab18 Merge branch 'master' into pref_defaults 2022-08-30 13:28:53 -05:00
Thomas GöttgensandGitHub 221843e176 Merge pull request #1663 from lewisxhe/master 2022-08-30 20:27:41 +02:00
Ben MeadorsandGitHub 0063ae6512 Merge branch 'master' into pref_defaults 2022-08-30 08:24:34 -05:00
lewishe 1922034c44 Add t-beam sx1268 support 2022-08-30 11:59:57 +08:00
Ben MeadorsandGitHub 7f586f7099 Better logging and cleanup (#1662) 2022-08-29 07:31:02 -05:00
lewis heandGitHub 0efa1b25c5 Add t-echo sx1268 support (#1657) 2022-08-29 07:26:17 -05:00
Sacha Weatherstone 1b25ea714d Set config.lora.hop_limit to HOP_RELIABLE 2022-08-27 19:03:26 +10:00
fd27a40edb Reboot after factory reset (#1653)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2022-08-25 12:07:20 -05:00
Ben MeadorsandGitHub 1013aff9b6 Screen changes and fixes (#1651)
* Fixed bluetooth reinit bug

* Remove screen transition ms

* Whoops

* hasScreen is smarter now

* Oops
2022-08-25 11:25:05 -05:00
Ben MeadorsandGitHub d7e5eb4d22 Upgrade unishox-2 to 1.0.3 (#1650) 2022-08-25 07:12:38 -05:00
Ben MeadorsandGitHub 9a03b2e49d Same as NodeDB position_broadcast_secs bug but different (#1645)
* intervalMs
2022-08-24 17:29:09 -05:00
e7831f13c5 [create-pull-request] automated change (#1641)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2022-08-24 17:28:43 -05:00
Ben Meadors ddc3727155 Fixed NRF52 bluetooth 2022-08-23 14:03:10 -05:00
Ben Meadors ef9bfc9104 Enable external notification module for nrf52 2022-08-23 13:16:20 -05:00
Ben Meadors 3bb645d4fe Fixed huge nodeinfo bug 2022-08-23 13:12:41 -05:00
Ben MeadorsandGitHub 8f99258fc4 Update main_matrix.yml 2022-08-22 18:31:56 -05:00
Ben MeadorsandGitHub b54073a8a1 Bluetooth mode unification and behavior tweaks (#1636)
* Esp32 bluetooth modes

* Comment

* Gutting bluetooth

* Cleanup

* Security

* Testing

* NRF bluetooth security

* Reboot on saved lora or bluetooth settings

* Cleanup

* Fixes

* Stub for platforms without screens

* Fixed just-works in esp32

* Cleanup

* Display device name in boot screen

* Added waypoint module routing

* chmod

* Words

* Protos

* Backing out partition changes for testing

* Revert "Backing out partition changes for testing"

This reverts commit 191ed6489c.

* Chmod PR artifacts

* Trying setInitialState again

* Revert "Trying setInitialState again"

This reverts commit 703eac7277.

* External notification module

* Cleanup

* Pin display formatting
2022-08-22 16:41:23 -05:00
Ben MeadorsandGitHub c85e9f53c7 Chmod PR artifacts 2022-08-20 12:53:34 -05:00
Ben MeadorsandGitHub 4cfc229e77 Update device-update.sh 2022-08-19 13:35:54 -05:00
Ben MeadorsandGitHub bbd7c5063d Removed ota erasure 2022-08-19 13:34:41 -05:00
Ben MeadorsandGitHub 05df849a6d Repartitioned 2022-08-19 13:33:58 -05:00
Ben MeadorsandGitHub ccbc01a753 Repartitioned 2022-08-19 13:33:02 -05:00
Sacha WeatherstoneandGitHub d6d936b5d2 Remove OTA partition (#1635) 2022-08-18 16:19:32 -05:00
Ben MeadorsandGitHub b028af0d82 Bluetooth modes (#1633)
* Formatting and comments

* Esp32 bluetooth modes

* Comment
2022-08-16 20:42:43 -05:00
Ben MeadorsandGitHub 86d3759f55 New bluetooth config protos and canned messages consolidation (#1632)
* Bluetooth and canned messages refactor

* More can of worms messages

* Set has_bluetooth and default pin

* Defaults
2022-08-15 21:06:55 -05:00
aadaf332cf add stm32wl5e platform and wio-e5 variant (#1631)
Co-authored-by: Peter Lawrence <12226419+majbthrd@users.noreply.github.com>
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2022-08-15 07:54:45 -05:00
Ben MeadorsandGitHub 4dea95d03f Update version.properties 2022-08-14 20:22:52 -05:00
Ben MeadorsandGitHub 1253abd138 Syntax error 2022-08-14 15:56:55 -05:00
Ben MeadorsandGitHub 80e3cee006 NimBLE enhanced logging (do not merge) (#1629)
* Change log level to debug

* Don't reinit active bluetooth services

* Chmod +x before zip and adding to release
2022-08-14 15:27:21 -05:00
Ben MeadorsandGitHub ca9113ad05 Update version.properties 2022-08-14 15:16:47 -05:00
GUVWAFandGitHub 63c8f15d38 Resend implicit ACK for a repeated broadcast (#1628) 2022-08-13 10:09:43 -05:00
Ben MeadorsandGitHub 73a1ea59f4 Update BMP280Sensor.cpp (#1627) 2022-08-12 20:11:32 -05:00
Ben MeadorsandGitHub 97712a9dc4 Update ESP32Bluetooth.cpp (#1625)
* Update ESP32Bluetooth.cpp

* Update ESP32Bluetooth.h
2022-08-12 14:14:14 -05:00
Ben MeadorsandGitHub 20e43fcf34 Update version.properties 2022-08-12 13:55:02 -05:00
f66c8572b4 use fixed-size buffer in RedirectablePrint::vprintf() (#1622)
Co-authored-by: Peter Lawrence <12226419+majbthrd@users.noreply.github.com>
Co-authored-by: Garth Vander Houwen <garthvh@yahoo.com>
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2022-08-12 13:41:16 -05:00
Ben MeadorsandGitHub 64f852e3f7 Update main_matrix.yml 2022-08-12 07:21:20 -05:00
Ben MeadorsandGitHub ea90e4d2de Update main_matrix.yml 2022-08-12 07:04:36 -05:00
Ben Meadors dd720f2fe6 Tweak 2022-08-11 19:23:51 -05:00
Ben MeadorsandGitHub 808fef7e91 Update main_matrix.yml 2022-08-11 18:50:02 -05:00
Ben Meadors 70e6dc3c67 chmod 2022-08-11 17:54:48 -05:00
Ben Meadors 279149e40f version.properties bump 2022-08-11 17:35:32 -05:00
Ben Meadors 4588995fba Chmod bump_version 2022-08-11 16:30:22 -05:00
Ben MeadorsandGitHub 11ae248c5e Update main_matrix.yml 2022-08-11 16:19:27 -05:00
Ben MeadorsandGitHub a0a5147c42 Update main_matrix.yml 2022-08-11 15:58:16 -05:00
Ben MeadorsandGitHub b8aac2c5b6 Create bump_version.py 2022-08-11 15:27:44 -05:00
Ben MeadorsandGitHub de22f20876 Turn region screen back on (#1621) 2022-08-11 14:24:35 -05:00
Ben MeadorsandGitHub 9b5211dc65 Syntax 2022-08-11 09:03:18 -05:00
Ben MeadorsandGitHub 0b4fb72d58 Guard the assets (#1618)
* Guard the assets

* Indicated legacy build-all

* Hopefully fixed
2022-08-11 08:56:38 -05:00
Ben Meadors 7e03019cc4 Zip elfs 2022-08-11 07:22:19 -05:00
Ben Meadors 780f4383f4 Trying elves again 2022-08-11 07:07:04 -05:00
Ben Meadors 8148f06773 Paths 2022-08-10 20:59:45 -05:00
Ben Meadors d5780af362 Elves live in trees 2022-08-10 20:24:37 -05:00
Ben Meadors 82ed7a2084 Elves are released 2022-08-10 20:09:01 -05:00
Ben Meadors dd5fd3744d Debug elfs 2022-08-10 19:25:27 -05:00
Ben Meadors afb5fca6e1 Correct path 2022-08-10 19:21:59 -05:00
Ben Meadors 95d75fdfee Bins 2022-08-10 19:06:31 -05:00
Ben Meadors 029a6b16ba Release the correct archiva 2022-08-10 18:47:06 -05:00
Ben Meadors 9be3099ca6 Remove release workflow 2022-08-10 18:10:15 -05:00
Ben Meadors b6126e6e63 Disable release workflow 2022-08-10 18:07:11 -05:00
Ben MeadorsandGitHub d6dfdc314e Update version.properties 2022-08-10 18:05:32 -05:00
Ben Meadors 78666e9b36 Oops 2022-08-10 18:00:41 -05:00
Ben Meadors 3abba0ce39 Release in CI hopefully 2022-08-10 17:59:47 -05:00
Ben Meadors 2c8e030b3d Bump whitespace for build 2022-08-10 16:32:27 -05:00
Ben Meadors eed7408f00 Remove checks from pico for now 2022-08-10 16:28:11 -05:00
Ben Meadors cabd1eb8c0 plz work 2022-08-10 16:17:49 -05:00
Ben Meadors f46c11a047 Line break 2022-08-10 16:12:35 -05:00
Ben Meadors cdd5e16e25 Path 2022-08-10 16:10:03 -05:00
Ben Meadors a6c9a819f8 Chmod path 2022-08-10 16:05:10 -05:00
Ben Meadors 2e72397898 Chmod 2022-08-10 16:03:41 -05:00
Ben Meadors f554226226 Add print back 2022-08-10 15:53:19 -05:00
Ben Meadors 2d1897a36f chmod 2022-08-10 15:52:53 -05:00
Ben MeadorsandGitHub fe1ed3f284 Pico build in PR (#1617)
* Pico build in PR

* Missed refs

* Update main_matrix.yml
2022-08-10 15:33:42 -05:00
Ben MeadorsandGitHub 3251cd510a Bump version 2022-08-10 13:11:32 -05:00
Ben MeadorsandGitHub 7d0411cd15 Esp32 NimBLE experiments (#1613)
* Delete callbacks on bleServer on destruct

* Trying things
2022-08-10 12:44:52 -05:00
Thomas GöttgensandGitHub 1d1ccd6b19 Merge pull request #1615 from meshtastic/src-cleanup
Put a bit of order in the src directory
2022-08-10 16:04:44 +02:00
Thomas GöttgensandGitHub 3b8566747c Merge branch 'master' into src-cleanup 2022-08-10 15:47:08 +02:00
Thomas GöttgensandGitHub 3cc584d855 Merge pull request #1616 from neilhao/master
'Station-g1-patch1'
2022-08-10 15:46:26 +02:00
neil 90d3cc2ff8 'Station-g1-patch1' 2022-08-10 19:26:43 +08:00
Thomas GöttgensandGitHub d125b0ec3c Merge branch 'master' into src-cleanup 2022-08-10 11:39:47 +02:00
Thomas Göttgens 5e842dd735 Put a bit of order in the src directory, group and name things appropriately 2022-08-10 11:31:29 +02:00
Thomas GöttgensandGitHub bbc0baa31d Merge pull request #1611 from meshtastic/RP2040-Platform
Raspberry Pi Pico target (with sparkfun lora hat)
2022-08-10 10:14:43 +02:00
Thomas GöttgensandGitHub 31788feab1 Update platformio.ini 2022-08-10 10:03:47 +02:00
Thomas Göttgens 2c37be58ac Merge branch 'RP2040-Platform' of github.com:meshtastic/Meshtastic-device 2022-08-10 10:01:58 +02:00
Thomas GöttgensandGitHub 836782b3c1 Merge branch 'master' into RP2040-Platform 2022-08-10 10:01:36 +02:00
Thomas Göttgens cfc44cd608 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-08-10 10:00:40 +02:00
Thomas Göttgens 519f31ed60 fix portduino build 2022-08-10 10:00:23 +02:00
Sacha Weatherstone e04d6b3f56 Update protobufs 2022-08-09 12:22:46 +10:00
Thomas GöttgensandGitHub 25c851a929 Merge branch 'master' into RP2040-Platform 2022-08-08 23:17:33 +02:00
Thomas Göttgens 0c8fb6e27f Raspberry Pi Pico target (with sparkfun lora hat) does compile but needs further work.
Also contains a small fix to make PRIVATE_HW targets build again for nRF52 architectures
2022-08-08 23:11:19 +02:00
Thomas GöttgensandGitHub 8490bdd14e Merge pull request #1609 from meshtastic/AXP192-CLEANUP
Axp192 cleanup
2022-08-08 16:50:57 +02:00
Thomas Göttgens 22a5cf04d3 Another one. 2022-08-08 16:29:34 +02:00
Thomas Göttgens ddc5a59ece Missed one or two 2022-08-08 16:16:50 +02:00
Thomas Göttgens 6382f67b89 Replace TBEAM_V10 macro guards with more appropriate HAS_AXP192. Also eliminates symbol redefinition of AXP192_SLAVE_ADDRESS 2022-08-08 16:13:38 +02:00
Ben MeadorsandGitHub 401b5d92aa 1.3.34 2022-08-08 07:29:36 -05:00
Ben MeadorsandGitHub 572f9f9295 Get device metadata admin message (#1607)
* Get device metadata admin message

* Bump device state version
2022-08-08 07:19:04 -05:00
Thomas GöttgensandGitHub 96ce40040c Merge pull request #1608 from meshtastic/compass-orientation
wire in compass display setting
2022-08-08 09:30:30 +02:00
Thomas Göttgens d0a1aad7d1 wire in compass display setting 2022-08-08 09:00:29 +02:00
Ben MeadorsandGitHub ab0095cb05 1.3.33 release 2022-08-07 16:06:18 -05:00
Ben MeadorsandGitHub 591ae7a803 Change state order to send node info before config (#1606)
* Change state order to send node info before config

* Kill groups
2022-08-07 16:03:58 -05:00
Ben MeadorsandGitHub de47cc55a0 Don't reply with null island (#1605) 2022-08-07 15:08:46 -05:00
Garth Vander HouwenandGitHub 7e6c22f542 Update version.properties 2022-08-06 12:56:10 -07:00
Garth Vander HouwenandGitHub 2fac581fa3 Merge pull request #1602 from meshtastic/WiFi_enum
Combine WIFI state into an enum
2022-08-06 12:55:45 -07:00
Garth Vander HouwenandGitHub 1155727a45 Merge branch 'master' into WiFi_enum 2022-08-06 12:38:19 -07:00
Ben MeadorsandGitHub 1c8e64319c Update nimble to 1.4 (#1600)
* Update nimble version

* Back down a version

* Nimble 1.4

* Change log level of Nimble. Too chatty

* Log level

* Log level of 1 (error)
2022-08-06 14:16:11 -05:00
Sacha Weatherstone ca1e687fd4 update protobufs 2022-08-06 21:29:59 +10:00
Sacha Weatherstone 4c215530f6 Update protobufs 2022-08-06 16:35:52 +10:00
Sacha Weatherstone 472fb6e5b0 Update protobufs & fix build 2022-08-06 16:31:40 +10:00
Garth Vander HouwenandGitHub 00846439d0 Update version.properties 2022-08-05 16:52:10 -07:00
Ben MeadorsandGitHub a10e56265b Update nimble version (#1599)
* Update nimble version

* Back down a version
2022-08-05 16:11:22 -05:00
Ben MeadorsandGitHub 9fe2ddb082 1.3.30 2022-08-04 07:33:02 -05:00
Thomas GöttgensandGitHub a9ad314307 Merge pull request #1551 from loodydo/loodydo-Compass-Fix
Update Screen.cpp
2022-08-04 11:34:38 +02:00
Thomas GöttgensandGitHub 688ac3f8ee Merge branch 'master' into loodydo-Compass-Fix 2022-08-04 11:01:02 +02:00
Thomas GöttgensandGitHub e79ef0dd35 Merge pull request #1596 from meshtastic/eink-speedup
Skip unneccessary EINK update
2022-08-04 11:00:48 +02:00
Thomas Göttgens 9bc2b4d8d7 Skip unneccessary EINK update 2022-08-04 10:35:40 +02:00
Thomas GöttgensandGitHub 720cd62943 Merge pull request #1572 from meshtastic/patch1
Tryfix LED T-Echo
2022-08-04 10:14:47 +02:00
Thomas GöttgensandGitHub 4073ba7572 Merge branch 'master' into patch1 2022-08-04 10:02:44 +02:00
Thomas GöttgensandGitHub 39aa7f9880 Merge pull request #1594 from meshtastic/littlefs-rename-fix
Littlefs rename fix
2022-08-04 09:37:34 +02:00
Thomas Göttgens 71a9f46451 change to logical and operator 2022-08-04 09:12:56 +02:00
Thomas Göttgens 18d5712ecd This code was committed by mistake 2022-08-04 09:10:50 +02:00
Thomas Göttgens 295dca8415 Work around bug in littlefs rename() for now. After upstream change to version 2.5 this can be reverted. 2022-08-04 09:08:02 +02:00
Thomas Göttgens 7b438cd16b Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-08-04 08:30:35 +02:00
Jm CaslerandGitHub d285a2e70a Merge pull request #1593 from GUVWAF/master
Rebroadcast encrypted messages
2022-08-03 12:28:33 -07:00
GUVWAF 2ad9e238e2 RoutingModule can handle encrypted packets 2022-08-03 19:08:23 +02:00
Thomas Göttgens 2d2f306982 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-08-03 15:18:29 +02:00
Ben MeadorsandGitHub 7afc14991e Bump for release 2022-08-03 07:38:20 -05:00
Ben MeadorsandGitHub 86095323e5 Add station-g1 to PR build (#1588) 2022-08-03 07:36:29 -05:00
Ben MeadorsandGitHub 01ac8d10b5 Add station-g1 to release (#1589) 2022-08-03 07:28:43 -05:00
Ben MeadorsandGitHub 874d308b50 Only save devicestate on GPS reset (#1587) 2022-08-03 07:16:41 -05:00
Thomas GöttgensandGitHub 1f8878bd89 Merge branch 'master' into loodydo-Compass-Fix 2022-08-03 11:37:48 +02:00
Thomas GöttgensandGitHub b39b58c87b Merge branch 'master' into patch1 2022-08-03 11:37:36 +02:00
Thomas GöttgensandGitHub fab20f5acf Merge pull request #1584 from neilhao/master
'station-g1'
2022-08-03 10:44:35 +02:00
Thomas GöttgensandGitHub 21f75686a4 Merge branch 'master' into master 2022-08-03 10:15:57 +02:00
Neil HaoandGitHub 4ad2e58047 Update mesh.pb.h 2022-08-03 16:15:11 +08:00
Thomas GöttgensandGitHub e26975ca12 Merge pull request #1586 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-08-03 10:14:28 +02:00
Neil HaoandGitHub 47da3b695a Update mesh.pb.h 2022-08-03 16:13:21 +08:00
caveman99andGitHub 151321ac3c [create-pull-request] automated change 2022-08-03 08:09:05 +00:00
neil faac761dc0 'station-g1' 2022-08-03 04:23:32 +08:00
Thomas Göttgens 5e2acc43f5 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-08-02 10:03:16 +02:00
Thomas GöttgensandGitHub 25a229ce85 Merge branch 'master' into loodydo-Compass-Fix 2022-08-02 09:39:29 +02:00
Garth Vander HouwenandGitHub 41f9541f95 Update version.properties 2022-08-01 16:06:27 -07:00
d64c552865 Rebroadcast direct message until (implicit) ACK (#1578)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
2022-08-01 16:59:50 -05:00
Thomas GöttgensandGitHub 785c2b32da Merge pull request #1583 from tschundler/fixdef
Respect GPS pins set in variant.h
2022-08-01 08:54:28 +02:00
Ted Schundler ba9d52da25 Respect GPS pins set in variant.h 2022-07-31 19:06:48 -07:00
Ben MeadorsandGitHub 44ffdc5172 Send to phone like position packets (#1582) 2022-07-31 11:13:12 -05:00
Thomas GöttgensandGitHub edd6f049cf Merge branch 'master' into patch1 2022-07-31 16:14:33 +02:00
Ben MeadorsandGitHub 97684c6c73 Add bmp-280 support (#1581) 2022-07-31 08:52:47 -05:00
ade32b1827 lay groundwork for a possible future architecture (#1571)
* lay groundwork for a possible future architecture

* switch from feature opt-out to feature opt-in

* lay groundwork for a possible future architecture

* switch from feature opt-out to feature opt-in

* fix USE_RTC in variant.h for rak4631_epaper and t-echo

* ensure Screen.h is not included without configuration.h

Co-authored-by: Peter Lawrence <12226419+majbthrd@users.noreply.github.com>
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2022-07-31 07:11:47 -05:00
Thomas Göttgens 69ac8c0353 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-07-31 10:32:14 +02:00
fd27a814b7 Don't send me to null island, please (#1576)
* Don't send me to null island, please

* Typo

Co-authored-by: Sacha Weatherstone <sachaw100@hotmail.com>
2022-07-30 07:36:21 -05:00
neilhaoandGitHub f0518bc99a 'BATTERY_SENSE_SAMPLES' (#1577) 2022-07-30 07:12:28 -05:00
Ben MeadorsandGitHub 13a287ce5c firmare (#1575) 2022-07-29 17:58:42 -05:00
Ben MeadorsandGitHub 7e7872605b Lots of environmental telemetry sensor cleanup (#1574) 2022-07-29 12:39:46 -05:00
Ben MeadorsandGitHub a41735544b Merge branch 'master' into loodydo-Compass-Fix 2022-07-28 07:25:56 -05:00
Thomas Göttgens dcc6a4b5e7 Tryfix LED T-Echo 2022-07-28 09:37:16 +02:00
Jm CaslerandGitHub c88ba583c6 Bump to .27 2022-07-25 11:07:16 -07:00
Thomas GöttgensandGitHub b36cd32c03 Merge pull request #1563 from meshtastic/patch1
Fix formula to consider Bandwidth in kHz
2022-07-21 10:20:41 +02:00
Thomas Göttgens 43733ce150 Fix formula to consider Bandwidth in kHz 2022-07-21 10:07:08 +02:00
Jm CaslerandGitHub 0010231172 Update to .26 2022-07-19 09:43:08 -07:00
Jm CaslerandGitHub 50300957db Merge pull request #1561 from mc-hamster/master
Updated the frequency selection formula
2022-07-19 09:38:11 -07:00
Jm CaslerandGitHub 07d4773722 Merge branch 'meshtastic:master' into master 2022-07-19 07:37:12 -07:00
Jm Casler 62aa740c93 Updated channel selection formula 2022-07-19 07:36:55 -07:00
Ben MeadorsandGitHub c292e539d4 Merge branch 'master' into loodydo-Compass-Fix 2022-07-17 18:27:35 -05:00
Jm CaslerandGitHub 4de6d5bdb0 Merge pull request #1560 from mc-hamster/master
Allow range test module to loop back messages
2022-07-16 11:56:17 -07:00
Jm cf4c814b59 Allow range test module to loop back messages 2022-07-16 08:08:10 -07:00
Jm CaslerandGitHub ca8e307976 Merge pull request #1559 from mc-hamster/master
fix comments in smart position
2022-07-16 07:58:21 -07:00
Jm CaslerandGitHub b51b7d3eb7 Merge branch 'meshtastic:master' into master 2022-07-16 07:57:51 -07:00
Jm ea7da3178b Fixed comment 2022-07-16 07:57:35 -07:00
Jm CaslerandGitHub 3011d09c8c Merge pull request #1557 from kokroo/master
Allow up to 500mW transmission power for EU868 region
2022-07-15 08:40:36 -07:00
Shiv Kokroo d179f02519 Removed comment about frequency hopping
Removed comment about frequency hopping due to lack of universal hardware support
2022-07-15 16:37:53 +02:00
Shiv Kokroo 67a7056025 Change page number to section for reference document 2022-07-15 16:37:01 +02:00
Shiv Kokroo 930b023d10 Allow up to 500mW transmission power for EU868 region
The European Union regulations clearly state that the power limit for this frequency range is 500 mW, or 27 dBm. goTenna Mesh uses the same frequency range and power limit too.

It also states that we can use interference avoidance and spectrum access techniques to avoid a duty cycle.

It might be worthwhile in the future to implement frequency hopping to avoid duty cycling.

(Please refer to page 69 in the following document)
        https://ec.europa.eu/growth/tools-databases/tris/index.cfm/ro/search/?trisaction=search.detail&year=2021&num=528&dLang=EN
2022-07-15 16:06:41 +02:00
loodydoandGitHub 4daf2cc3fa Merge branch 'meshtastic:master' into loodydo-Compass-Fix 2022-07-14 22:00:13 -06:00
Ben MeadorsandGitHub 85f46d3231 Bump to 1.3.25 for release 2022-07-11 13:18:58 -05:00
Ben MeadorsandGitHub d56094fb7c Set last gps coordinates after comparison (#1556)
* Set last gps coordinates after comparison

* Wrong spot
2022-07-11 13:18:02 -05:00
loodydoandGitHub 9c21064634 Update Screen.cpp
Fixed variable shadowing
2022-07-09 11:47:50 -06:00
loodydoandGitHub 20d7d1b162 Update Screen.cpp
Add option to switch between static/non-static North.
2022-07-09 11:38:41 -06:00
loodydoandGitHub 97a2bf6221 Merge branch 'meshtastic:master' into loodydo-Compass-Fix 2022-07-09 10:57:20 -06:00
Jm CaslerandGitHub dff69157d6 bump to 24 2022-07-08 17:57:08 -07:00
Jm CaslerandGitHub 38088253f8 disable welcome screen 2022-07-08 17:56:49 -07:00
Ben MeadorsandGitHub 7485c312dd Merge branch 'master' into loodydo-Compass-Fix 2022-07-06 07:03:48 -05:00
Jm CaslerandGitHub 0e560b376f Merge pull request #1535 from mc-hamster/master
Add ability to adjust frequency by config.lora.frequency_offset
2022-07-05 19:56:24 -07:00
Jm CaslerandGitHub 6ff5ada7d6 Merge branch 'master' into loodydo-Compass-Fix 2022-07-05 19:23:12 -07:00
loodydoandGitHub cf331dc58b Update Screen.cpp 2022-07-04 13:16:29 -06:00
Ben MeadorsandGitHub 8c2af4f3d5 Merge branch 'master' into master 2022-07-04 13:19:56 -05:00
Ben MeadorsandGitHub d7d574e0a7 Screen for voltage / current (#1547)
* Add voltage + current measurements

* mA instead of amp
2022-07-03 11:10:41 -05:00
Ben MeadorsandGitHub 5462d84bfc Bump for release 2022-07-02 14:51:50 -05:00
Ben MeadorsandGitHub 1efcd5e125 Merge branch 'master' into master 2022-07-02 14:44:40 -05:00
Ben MeadorsandGitHub 9fd7abf3d4 Actually save nodeDb after we init (#1546) 2022-07-02 10:16:48 -05:00
Ben MeadorsandGitHub 4a08f86f96 Oops (#1545) 2022-07-02 09:25:01 -05:00
Ben MeadorsandGitHub 3f0ff45232 Node db cleanup and debug prints (#1543)
* Node db cleanup and debug prints

* File name cleanup
2022-07-02 09:09:41 -05:00
f8ee1ac4f9 Update GeoCoord.cpp (#1540)
Adding clarification to comments on GeoCoord::bearing function.

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2022-07-02 07:05:10 -05:00
f26441727c Update MQTT.cpp (#1534)
Fix returning pointer to local variable that will become invalid when returning.

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2022-07-02 06:53:15 -05:00
Ben MeadorsandGitHub c725a6b65f Bump for next tech preview release 2022-06-29 20:17:51 -05:00
Ben MeadorsandGitHub 9c6da233b9 Phoneapi moduleconfig (#1538) 2022-06-29 19:41:43 -05:00
0f2aa7660d [create-pull-request] automated change (#1537)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2022-06-29 19:09:38 -05:00
Jm CaslerandGitHub 004a6f9c25 Merge branch 'master' into master 2022-06-25 22:59:58 -07:00
Jm Casler d81b043f1d Add ability to adjust frequency by config.lora.frequency_offset 2022-06-25 22:43:13 -07:00
Thomas GöttgensandGitHub 9f78dff25f Merge pull request #1532 from meshtastic/patch-1
avoid BLE device names like a123_a123
2022-06-22 15:44:25 +02:00
Thomas Göttgens e7dfd14917 Change recursive delete to be recursive 2022-06-22 15:33:53 +02:00
Thomas Göttgens bc47dd574b avoid BLE device names like a123_a123 2022-06-22 14:26:33 +02:00
Thomas GöttgensandGitHub 41d5ccc29f Merge pull request #1531 from meshtastic/patch-1
Small fixes and inprovements
2022-06-22 12:36:46 +02:00
Thomas Göttgens aead7a23f9 - Put Modemconfig in logical order and fix typo
- non-zero config.lora.bandwidth means a custom radio config, not 'Unknown'
- Enable 'this is a new device, set region' screen again now we can actually set region.
2022-06-22 09:52:08 +02:00
Thomas Göttgens c9fd591942 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-06-22 09:44:59 +02:00
Jm CaslerandGitHub c81fbd867d Merge pull request #1530 from mc-hamster/master
Add debug to monitor radio reconfiguration for #1014
2022-06-21 22:18:13 -07:00
Jm CaslerandGitHub cfb76290cb Merge branch 'master' into master 2022-06-21 21:52:55 -07:00
Jm Casler 46e13d23d9 Add debug to monitor radio reconfiguration for #1014 - 2022-06-21 21:51:45 -07:00
Jm CaslerandGitHub 45b2c169aa Merge pull request #1529 from mc-hamster/master
Fix typo in the modem presets
2022-06-21 19:34:37 -07:00
Jm Casler 90baf9d8a0 Fix typo in the modem presets 2022-06-21 19:23:07 -07:00
Jm CaslerandGitHub a390fc7ea8 Merge pull request #1528 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-06-21 19:07:36 -07:00
mc-hamsterandGitHub e0f912ab2a [create-pull-request] automated change 2022-06-22 02:06:51 +00:00
Thomas Göttgens 646d6f5615 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-06-21 10:09:22 +02:00
Jm CaslerandGitHub cf00ac593f Update to 1.3.21 2022-06-20 16:44:33 -07:00
Thomas Göttgens ff9f973a1d Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-06-20 20:33:43 +02:00
Ben MeadorsandGitHub 7a50ab4de2 Re-init config_state after we switch to nodeinfo (#1526) 2022-06-20 13:28:50 -05:00
Thomas Göttgens c80f260fba Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-06-20 20:26:13 +02:00
Ben MeadorsandGitHub a7d527c3c3 Pins for m5stack-core 2022-06-20 12:41:03 -05:00
2e2c485f4c M5Stack CoreInk Pins_Arduino.h (#1527)
* Update EInkDisplay2.cpp

* Create pins_arduino.h

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2022-06-20 12:33:44 -05:00
Ben MeadorsandGitHub 388865aba7 Dashes not underscores 2022-06-20 11:19:20 -05:00
Ben MeadorsandGitHub 21c6e595a1 Update build-all.sh 2022-06-20 11:18:30 -05:00
Ben MeadorsandGitHub 4a2522dbd3 Add m5stack core targets to release 2022-06-20 09:16:00 -05:00
Ben MeadorsandGitHub 877d72cbad Helps if you get the name right 2022-06-20 09:15:30 -05:00
Ben MeadorsandGitHub 63238cb810 Add m5stack core boards to CI 2022-06-20 09:13:27 -05:00
e87c5d8d34 Update EInkDisplay2.cpp (#1524)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2022-06-20 09:08:35 -05:00
Ben MeadorsandGitHub f9bbbfccb3 Fix typo 2022-06-18 14:03:58 -05:00
Thomas Göttgens 089c91a7ac Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-06-18 09:48:22 +02:00
Ben MeadorsandGitHub 9a5ff935f9 Bump to 1.3.20 2022-06-17 16:40:33 -05:00
Thomas Göttgens 515a411e8c Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-06-17 22:37:55 +02:00
Ben MeadorsandGitHub 52f299ec49 Remove is_always_pwoered (#1525) 2022-06-17 13:35:12 -05:00
Ben MeadorsandGitHub 9285316c78 Upgrade to nanopb 0.4.6 (#1523) 2022-06-17 08:37:52 -05:00
Thomas Göttgens cf380e6cb6 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-06-17 09:01:14 +02:00
Thomas GöttgensandGitHub c3c359c0cb Merge pull request #1519 from meshtastic/LocalConfig
Push of Config-Protos on PhoneAPI init
2022-06-17 08:47:41 +02:00
Thomas GöttgensandGitHub 68465f294a Merge branch 'master' into LocalConfig 2022-06-16 21:59:55 +02:00
Thomas Göttgens f63b876b71 Send config chunks one by one 2022-06-16 21:56:18 +02:00
Thomas GöttgensandGitHub 22fca01323 Merge pull request #1522 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-06-16 21:41:23 +02:00
caveman99andGitHub d4a4bcf91a [create-pull-request] automated change 2022-06-16 19:31:21 +00:00
Thomas GöttgensandGitHub d726ed6e7c Merge pull request #1425 from holdenk/sketch
Configure bluetooth name based on owner's short name
2022-06-16 21:26:39 +02:00
Thomas GöttgensandGitHub 349f6bf502 Merge branch 'master' into sketch 2022-06-16 21:13:19 +02:00
Thomas GöttgensandGitHub 192c10d6d7 Merge pull request #1521 from meshtastic/1510-enhancement-change-default-device-name-from-unknown-xxxx-to-meshtastic-xxxx-to-match-ble-name
Fix #1510
2022-06-16 21:13:09 +02:00
Thomas GöttgensandGitHub be8fb73204 Merge branch 'master' into sketch 2022-06-16 20:59:11 +02:00
Thomas GöttgensandGitHub bc9a4367d1 Fix #1510 2022-06-16 20:58:15 +02:00
Thomas GöttgensandGitHub 3d3511ceeb Change to a different logic 2022-06-16 20:54:50 +02:00
Thomas Göttgens 74e926ef00 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-06-16 20:44:43 +02:00
Ben MeadorsandGitHub f3a433f906 Merge branch 'master' into LocalConfig 2022-06-16 08:10:20 -05:00
Jm CaslerandGitHub 3c6a2f7bb6 Bump to 1.3.19 2022-06-16 05:24:08 -07:00
Thomas GöttgensandGitHub 1996a2a193 Merge pull request #1520 from meshtastic/radiolib-fix
Tryfix Portduino Radiolib
2022-06-16 12:30:23 +02:00
Thomas Göttgens b40abbf3ad Tryfix Portduino Radiolib 2022-06-16 12:22:01 +02:00
Thomas Göttgens af335e9c06 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-06-16 09:46:17 +02:00
Jm CaslerandGitHub 8684fd1c49 Bump to .18 2022-06-15 19:00:40 -07:00
Thomas GöttgensandGitHub 49e47f3e6d Let's try this 2022-06-15 21:50:33 +02:00
Thomas Göttgens d0a8a3018d Merge branch 'LocalConfig' of github.com:meshtastic/Meshtastic-device 2022-06-15 20:03:53 +02:00
Thomas Göttgens 7566ee1fea C++ is a weird language... 2022-06-15 20:03:08 +02:00
Thomas GöttgensandGitHub 43d48d4fb9 Merge branch 'master' into LocalConfig 2022-06-15 19:43:47 +02:00
Thomas GöttgensandGitHub 2a6633a666 Merge pull request #1518 from meshtastic/create-pull-request/patch
TEST: Push out LocalConfig Object on app Handshake
2022-06-15 19:43:05 +02:00
Thomas Göttgens 0146761850 TEST - Push of LocalConfig 2022-06-15 19:42:16 +02:00
caveman99andGitHub 0943e5f500 [create-pull-request] automated change 2022-06-15 17:40:08 +00:00
a1dc350231 Changed default baud to 115200 (#1517)
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
2022-06-15 11:44:37 -05:00
Thomas GöttgensandGitHub d5a258cebd Merge pull request #1516 from meshtastic/LocalConfig
add file version to local savefiles
2022-06-15 18:05:52 +02:00
Thomas Göttgens 125f76d984 Don't use rmdir_r but roll our own version. 2022-06-15 17:52:37 +02:00
Thomas Göttgens b127479961 - Refactored factory reset a bit to not installDefaultDeviceState twice on ESP32
- clear BLE bonds on settings version increase
2022-06-15 17:09:42 +02:00
Thomas Göttgens d18aa2e7cb add file version to local savefiles 2022-06-15 16:52:04 +02:00
Thomas GöttgensandGitHub d301144efe Merge pull request #1515 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-06-15 16:45:11 +02:00
caveman99andGitHub 058b5ceddd [create-pull-request] automated change 2022-06-15 14:44:33 +00:00
Thomas GöttgensandGitHub e85baf00c4 Merge pull request #1511 from meshtastic/radiolib-fix
Set TX Power to some meaningful value
2022-06-13 23:24:37 +02:00
Thomas Göttgens 4a6cad6e46 Set TX Power to some meaningful value 2022-06-13 23:00:50 +02:00
Thomas GöttgensandGitHub bc05f98685 Merge pull request #1499 from meshtastic/radiolib-fix
new radiolib version (use upstream)
2022-06-13 21:33:51 +02:00
Thomas Göttgens 6e671d808a Our mod was accepted by RadioLib 2022-06-13 21:25:27 +02:00
Thomas Göttgens 1df3dd5f78 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-06-13 21:21:46 +02:00
Jm CaslerandGitHub c9822dee93 Update to 1.13.17 2022-06-13 09:38:33 -07:00
Thomas Göttgens e1783df49f Merge branch 'radiolib-fix' of github.com:meshtastic/Meshtastic-device
# Conflicts:
#	src/mesh/RadioLibInterface.h
2022-06-13 16:13:13 +02:00
Thomas Göttgens 6b8afdadc2 New variant of Radiolib patch 2022-06-13 16:10:16 +02:00
Thomas Göttgens f918548e44 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-06-13 16:08:50 +02:00
a1b07ed6aa Introduce contention window (CW) (#1500)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2022-06-13 08:21:18 -05:00
Thomas Göttgens b059fb9e8e Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-06-13 12:23:51 +02:00
Ben MeadorsandGitHub 553b35d0ad Consolidate power saving prefs (#1507)
* Fixed conversion linter warning

* Power saving consolidation

* Whoops
2022-06-12 19:56:32 -05:00
Thomas GöttgensandGitHub 04478081c6 Merge pull request #1508 from meshtastic/crpytfix
Remove nRF Crypt Debug
2022-06-12 23:52:16 +02:00
Thomas Göttgens 7bd07db2a8 Remove nRF Crypt Debug 2022-06-12 23:35:59 +02:00
Thomas Göttgens 5c44c4f772 Remove Debug Code for Encryption 2022-06-12 23:29:27 +02:00
Thomas Göttgens 7ff940409e Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-06-12 23:28:04 +02:00
Ben MeadorsandGitHub cb5c32490c Merge branch 'master' into radiolib-fix 2022-06-12 15:27:58 -05:00
Thomas GöttgensandGitHub e0b63c6692 Merge pull request #1506 from meshtastic/1504-proposal-default-short-name-to-mac-last-4
implement #1504
2022-06-12 22:05:04 +02:00
Thomas GöttgensandGitHub dc8d1d9a84 implement #1504 2022-06-12 21:52:46 +02:00
Thomas GöttgensandGitHub 710e2694ef Merge branch 'master' into radiolib-fix 2022-06-12 20:32:00 +02:00
Thomas GöttgensandGitHub 7594140afc actual change to our interface 2022-06-12 20:31:23 +02:00
Thomas Göttgens e793d933c6 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-06-12 20:28:39 +02:00
Thomas GöttgensandGitHub 9d8f9613d4 Merge branch 'master' into sketch 2022-06-12 18:48:08 +02:00
Thomas GöttgensandGitHub 61427528b6 Merge pull request #1505 from meshtastic/caveman99-patch-1
fix C++ warnings
2022-06-12 18:39:46 +02:00
Thomas GöttgensandGitHub 47ad27f9f6 fix C++ warnings
The cast throws errors about ambiguous conversions. There's a prototype of requestFrom(uint8_t address, uint8_t length) so just use that one.
2022-06-12 17:59:16 +02:00
Thomas Göttgens 77f096e56c Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-06-12 17:37:43 +02:00
Ben MeadorsandGitHub 5106433572 Removed phone_timeout_secs pref references (#1503) 2022-06-12 09:44:23 -05:00
Ben MeadorsandGitHub 4458b470aa Don't enable environmental telemetry by default (#1502)
* INA219 + INA260 support in telemetry

* Protobuf update

* Fixes + debug statement

* Fix size

* Fix conversion from mv

* Added getRegisterValue for i2cscan

* Accidentally left this in

* Removed line
2022-06-12 07:14:33 -05:00
Ben MeadorsandGitHub 90957e6994 INA260 + INA219 sensor support (#1501)
* INA219 + INA260 support in telemetry

* Protobuf update

* Fixes + debug statement

* Fix size

* Fix conversion from mv

* Added getRegisterValue for i2cscan
2022-06-11 16:44:56 -05:00
Thomas GöttgensandGitHub b73fd32f71 Merge branch 'master' into radiolib-fix 2022-06-10 20:39:50 +02:00
Thomas Göttgens 2a3272b7d0 patch radiolib on-the-fly while building. 2022-06-10 20:38:56 +02:00
Ben MeadorsandGitHub 3fd756900a Refactoring some of the i2c boilerplate (#1498)
* Refactoring some of the i2c boilerplate

* Default value

* Debug statement
2022-06-10 12:04:04 -05:00
Thomas GöttgensandGitHub beb8bc9e72 Merge pull request #1496 from benner/fix/NodeDB_without_FSCom
Compile when FSCom is not defined (NodeDB.cpp)
2022-06-07 22:22:20 +02:00
Thomas GöttgensandGitHub 1ad5cdc93c Merge branch 'master' into fix/NodeDB_without_FSCom 2022-06-07 21:57:26 +02:00
Nerijus Bendžiūnas e8e72d2e08 Compile when FSCom is not defined (NodeDB.cpp) 2022-06-07 20:55:05 +03:00
Thomas GöttgensandGitHub 1d0badd468 Merge pull request #1495 from benner/fix/typo
Correctly print script name in platformio-custom.py
2022-06-07 11:39:47 +02:00
Nerijus Bendžiūnas 9e87be4f22 Correctly print script name in platformio-custom.py 2022-06-07 12:26:01 +03:00
Jm CaslerandGitHub 97899aed26 1.3.16 2022-06-06 22:10:18 -07:00
Thomas GöttgensandGitHub 0ee4ba4975 Merge pull request #1494 from meshtastic/fix-1493
fixes power LED on T-Echo and T-Beam
2022-06-06 19:23:23 +02:00
Thomas Göttgens bbcccde787 Merge branch 'fix-1493' of github.com:meshtastic/Meshtastic-device 2022-06-06 19:15:14 +02:00
Thomas Göttgens 42c285bc31 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-06-06 19:14:43 +02:00
Thomas Göttgens c831242f25 fix nrf build 2022-06-06 19:14:30 +02:00
Thomas GöttgensandGitHub 3c6f36c8f7 Merge branch 'master' into fix-1493 2022-06-06 18:57:51 +02:00
Thomas GöttgensandGitHub dfde6cc9c1 Merge pull request #1490 from meshtastic/CryptFix
Crypt fix. Please leave branch open
2022-06-06 18:57:27 +02:00
Thomas GöttgensandGitHub 7816800012 Merge branch 'master' into CryptFix 2022-06-06 18:49:38 +02:00
Thomas Göttgens ebf132ad21 Bug-1493 2022-06-06 18:48:22 +02:00
Thomas Göttgens 67cf3018b5 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-06-06 18:27:28 +02:00
Ben MeadorsandGitHub eafbef0c2f Scan for i2c sensors in environmental telemetry if enabled (#1492)
* Scan for i2c sensors in environmental telemetry if enabled

* Update TelemetrySensor.h

* Added surpression.

* Remove suppression and fix real bug

* Interrogate BME sensor id registers
2022-06-05 09:50:06 -05:00
Ben MeadorsandGitHub 4ab831c103 Fix nagging bool linter warnings (#1491) 2022-06-04 07:28:58 -05:00
Thomas GöttgensandGitHub 3df5ec0b11 Merge pull request #1479 from meshtastic/ProtoFix
If we get an unreadable buffer, don't try to process it.
2022-06-04 11:07:00 +02:00
Thomas GöttgensandGitHub c5c2765fb4 Merge branch 'master' into ProtoFix 2022-06-04 10:49:36 +02:00
Thomas Göttgens df9e9bc223 Bugfix for nRF Crypto 90% done, includes heavy debug code, do not merge for now. 2022-06-04 10:37:24 +02:00
Thomas Göttgens 1ff0032c20 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-06-04 10:35:42 +02:00
Jm CaslerandGitHub 18024f1d25 Merge pull request #1489 from mc-hamster/master
Disabled the unset welcome screen
2022-06-04 01:19:44 -07:00
Jm CaslerandGitHub 313c50d6cf Merge branch 'master' into master 2022-06-03 21:55:27 -07:00
Jm Casler 80e08f6de9 Disabled the unset welcome screen 2022-06-03 21:51:47 -07:00
Jm CaslerandGitHub 5a256323e2 Merge pull request #1488 from mc-hamster/master
Change default screen on to 10 minutes
2022-06-03 20:57:23 -07:00
Jm CaslerandGitHub 45495c51e6 Merge branch 'meshtastic:master' into master 2022-06-03 20:38:28 -07:00
Jm Casler 40ded630d0 Change default screen on to 10 minutes 2022-06-03 20:38:13 -07:00
Jm CaslerandGitHub 432d06741e Update version.properties 2022-06-03 18:49:18 -07:00
Jm CaslerandGitHub 03b7f2f837 Merge pull request #1487 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-06-03 18:47:52 -07:00
mc-hamsterandGitHub 2e1b895791 [create-pull-request] automated change 2022-06-04 01:47:29 +00:00
Jm CaslerandGitHub 9821a0535b Bump to 1.3.14 2022-06-03 14:32:32 -07:00
Thomas Göttgens 0b666b827d Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-06-03 15:38:50 +02:00
Thomas GöttgensandGitHub 235cacf9b9 Merge pull request #1485 from markbirss/master
Update EInkDisplay2.cpp
2022-06-03 15:09:56 +02:00
Mark Trevor BirssandGitHub db28a1562e Update EInkDisplay2.cpp
Fix E-Ink not powering up bug at startup
2022-06-03 14:21:27 +02:00
Jm CaslerandGitHub f61d2d9eb4 Merge pull request #1484 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-06-02 18:12:35 -07:00
mc-hamsterandGitHub 5aef58e87f [create-pull-request] automated change 2022-06-03 01:07:08 +00:00
Thomas GöttgensandGitHub 77a2054254 Merge pull request #1480 from markbirss/master
Add M5Stack CoreInk 1.54 inch e-Ink - HopeRF95 Support
2022-06-01 20:56:05 +02:00
Mark Trevor BirssandGitHub 48ee995e0d Update EInkDisplay2.cpp 2022-06-01 20:33:51 +02:00
Mark Trevor BirssandGitHub c7dfd245e3 Update EInkDisplay2.cpp 2022-06-01 20:31:39 +02:00
Mark Trevor BirssandGitHub 4e813b098a Update platformio.ini 2022-06-01 20:30:21 +02:00
Thomas GöttgensandGitHub e57dbdd26c Merge branch 'master' into master 2022-06-01 20:28:12 +02:00
Mark Trevor BirssandGitHub 9512ea45de Update EInkDisplay2.cpp 2022-06-01 19:27:38 +02:00
Mark Trevor BirssandGitHub 0d09767efd Update variant.h 2022-06-01 18:11:06 +02:00
Mark Trevor BirssandGitHub 5828e6f423 Update variant.h 2022-06-01 18:08:40 +02:00
Mark Trevor BirssandGitHub c7a9ce7f49 Update variant.h 2022-06-01 18:08:13 +02:00
Mark Trevor BirssandGitHub 95f091041b Update variant.h 2022-06-01 17:53:19 +02:00
Mark Trevor BirssandGitHub f33e6a0e66 Update platformio.ini 2022-06-01 17:49:10 +02:00
Mark Trevor BirssandGitHub fe8bfdb762 Update variant.h 2022-06-01 17:48:31 +02:00
Thomas Göttgens e8afd4fb4b If we get an unreadable buffer, don't try to process it. 2022-06-01 17:09:57 +02:00
Ben MeadorsandGitHub 71a43a97cc Bump to 13 2022-06-01 06:06:40 -05:00
Mark Trevor BirssandGitHub b34b26518b Update EInkDisplay2.cpp 2022-06-01 11:28:18 +02:00
Mark Trevor BirssandGitHub b9f25eb85c Update EInkDisplay2.cpp 2022-06-01 11:21:09 +02:00
Mark Trevor BirssandGitHub a7fbe024e4 Create variant.h 2022-06-01 11:12:45 +02:00
Mark Trevor BirssandGitHub 1f7fee8e2a Create platformio.ini 2022-06-01 11:10:49 +02:00
Mark Trevor BirssandGitHub b8e7c6ee7a Update platformio.ini 2022-06-01 11:09:21 +02:00
Ben MeadorsandGitHub 06b2ed4ebe Merge branch 'master' into sketch 2022-05-30 18:07:40 -05:00
Thomas GöttgensandGitHub 32245a1a8d Merge pull request #1477 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-05-30 21:40:52 +02:00
Thomas Göttgens f6982ca726 fix building with new peotobuf structure. 2022-05-30 21:12:27 +02:00
caveman99andGitHub 03bbc5eff4 [create-pull-request] automated change 2022-05-30 19:00:01 +00:00
Ben MeadorsandGitHub 0767c0b0e8 Converted to jgromes/RadioLib upstream and pegged to latest ref (#1472)
* Converted to jgromes/RadioLib upstream and pegged to latest ref
2022-05-29 19:30:20 -05:00
Thomas GöttgensandGitHub 0d574e35c6 Merge pull request #1473 from meshtastic/LocalConfig
fixed typo in AdminModule
2022-05-29 16:40:14 +02:00
Thomas Göttgens b88e75cf2a Fixed Typo in get Config 2022-05-29 16:31:30 +02:00
Ben MeadorsandGitHub 2ee003f2a1 Merge branch 'master' into sketch 2022-05-25 06:33:42 -05:00
Jm CaslerandGitHub 1ef70a2489 Merge branch 'master' into sketch 2022-05-24 00:23:17 -07:00
Holden Karau ca3192b3dc Clear the existing data before we start advertising 2022-04-30 18:20:41 -07:00
Holden Karau e1f28982cf When configured set meshtastic bluetooth name based on owner shortname. 2022-04-30 14:48:31 -07:00
268 changed files with 8190 additions and 6301 deletions
-146
View File
@@ -1,146 +0,0 @@
name: Continuous Integration (Legacy serial build)
on:
# Triggers the workflow on push or pull request events but only for the master branch
workflow_dispatch:
jobs:
ci-check:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
submodules: "recursive"
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Install cppcheck
run: |
sudo apt-get install -y cppcheck
- name: Setup Python
uses: actions/setup-python@v2
with:
python-version: 3.x
- name: Cache python libs
uses: actions/cache@v1
id: cache-pip # needed in if test
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip
- name: Upgrade python tools and install platformio
run: |
python -m pip install --upgrade pip
pip install -U platformio
- name: Upgrade platformio
run: |
pio upgrade
- name: Check everything
run: bin/check-all.sh
ci-build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
submodules: "recursive"
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Setup Python
uses: actions/setup-python@v2
with:
python-version: 3.x
- name: Cache python libs
uses: actions/cache@v1
id: cache-pip # needed in if test
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip
- name: Upgrade python tools
# We actually want to run this every time
# if: steps.cache-pip.outputs.cache-hit != 'true'
run: |
python -m pip install --upgrade pip
pip install -U platformio meshtastic adafruit-nrfutil
# - name: Cache platformio
# uses: actions/cache@v1
# id: cache-platformio # needed in if test
# with:
# path: ~/.platformio
# key: ${{ runner.os }}-platformio
- name: Upgrade platformio
run: |
pio upgrade
- name: Pull web ui
uses: dsaltares/fetch-gh-release-asset@master
with:
repo: "meshtastic/meshtastic-web"
file: "build.tar"
target: "build.tar"
token: ${{ secrets.GITHUB_TOKEN }}
- name: Unpack web ui
run: |
tar -xf build.tar -C data/static
rm build.tar
# We now run integration test before other build steps (to quickly see runtime failures)
- name: Build for native
run: platformio run -e native
- name: Integration test
run: |
.pio/build/native/program &
sleep 20 # 5 seconds was not enough
echo "Simulator started, launching python test..."
python3 -c 'from meshtastic.test import testSimulator; testSimulator()'
- name: Cat bin/build-all.sh
run: |
cat bin/build-all.sh
- name: Build everything
run: bin/build-all.sh
- name: Get release version string
run: echo "::set-output name=version::$(./bin/buildinfo.py long)"
id: version
- name: Store binaries as an artifact
uses: actions/upload-artifact@v2
with:
name: firmware-${{ steps.version.outputs.version }}.zip
path: release/archive/firmware-${{ steps.version.outputs.version }}.zip
retention-days: 90
- name: Store debugging elf files as an artifact
uses: actions/upload-artifact@v2
with:
name: debug-elfs
path: release/archive/elfs-*.zip
retention-days: 7
- name: Download firmware.zip
uses: actions/download-artifact@master
with:
name: firmware-${{ steps.version.outputs.version }}.zip
path: ./
- name: Pull request artifacts
if: ${{ github.event_name == 'pull_request_target' || github.event_name == 'pull_request' }}
uses: gavv/pull-request-artifacts@v1.0.0
with:
commit: ${{ (github.event.pull_request_target || github.event.pull_request).head.sha }}
repo-token: ${{ secrets.GITHUB_TOKEN }}
artifacts-branch: artifacts
artifacts: ./firmware-${{ steps.version.outputs.version }}.zip
+170 -11
View File
@@ -5,7 +5,6 @@ on:
branches: [master]
paths-ignore:
- "**.md"
- "**.yml"
- "version.properties"
# Note: This is different from "pull_request". Need to specify ref when doing checkouts.
@@ -13,7 +12,7 @@ on:
branches: [master]
paths-ignore:
- "**.md"
- "**.yml"
#- "**.yml"
workflow_dispatch:
@@ -38,7 +37,12 @@ jobs:
- board: rak4631_eink
- board: t-echo
- board: nano-g1
- board: station-g1
- board: m5stack-core
- board: m5stack-coreink
- board: tbeam-s3-core
# - board: pico
runs-on: ubuntu-latest
steps:
- name: Checkout code
@@ -93,6 +97,10 @@ jobs:
- board: tbeam0.7
- board: meshtastic-diy-v1
- board: nano-g1
- board: station-g1
- board: m5stack-core
- board: m5stack-coreink
- board: tbeam-s3-core
runs-on: ubuntu-latest
steps:
@@ -118,13 +126,12 @@ jobs:
- name: Upgrade python tools
run: |
python -m pip install --upgrade pip
pip install -U platformio adafruit-nrfutil littlefs-python
pip install -U --pre meshtastic
pip install -U platformio adafruit-nrfutil
- name: Upgrade platformio
run: |
pio upgrade
- name: Pull web ui
uses: dsaltares/fetch-gh-release-asset@master
with:
@@ -140,7 +147,15 @@ jobs:
- name: Build ESP32
run: bin/build-esp32.sh ${{ matrix.board }}
- name: Pull OTA Firmware
uses: dsaltares/fetch-gh-release-asset@master
with:
repo: "meshtastic/Meshtastic-OTA"
file: "firmware.bin"
target: "release/bleota.bin"
token: ${{ secrets.GITHUB_TOKEN }}
- name: Get release version string
run: echo "::set-output name=version::$(./bin/buildinfo.py long)"
id: version
@@ -190,7 +205,6 @@ jobs:
run: |
python -m pip install --upgrade pip
pip install -U platformio adafruit-nrfutil
pip install -U --pre meshtastic
- name: Upgrade platformio
run: |
@@ -212,6 +226,60 @@ jobs:
release/*.elf
retention-days: 90
build-rpi2040:
strategy:
fail-fast: false
max-parallel: 2
matrix:
include:
- board: pico
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
submodules: "recursive"
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Setup Python
uses: actions/setup-python@v2
with:
python-version: 3.x
- name: Cache python libs
uses: actions/cache@v1
id: cache-pip # needed in if test
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip
- name: Upgrade python tools
run: |
python -m pip install --upgrade pip
pip install -U platformio adafruit-nrfutil
- name: Upgrade platformio
run: |
pio upgrade
- name: Build Raspberry Pi 2040
run: ./bin/build-rpi2040.sh ${{ matrix.board }}
- name: Get release version string
run: echo "::set-output name=version::$(./bin/buildinfo.py long)"
id: version
- name: Store binaries as an artifact
uses: actions/upload-artifact@v2
with:
name: firmware-${{ matrix.board }}-${{ steps.version.outputs.version }}.zip
path: |
release/*.uf2
release/*.elf
retention-days: 90
build-native:
runs-on: ubuntu-latest
steps:
@@ -238,7 +306,7 @@ jobs:
run: |
python -m pip install --upgrade pip
pip install -U platformio adafruit-nrfutil
pip install -U --pre meshtastic
pip install -U meshtastic --pre
- name: Upgrade platformio
run: |
@@ -283,7 +351,7 @@ jobs:
gather-artifacts:
runs-on: ubuntu-latest
needs: [build-esp32, build-nrf52, build-native]
needs: [build-esp32, build-nrf52, build-native, build-rpi2040]
steps:
- name: Checkout code
uses: actions/checkout@v3
@@ -300,7 +368,7 @@ jobs:
id: version
- name: Move files up
run: mv -b -t ./ ./*tbeam-*/littlefs*.bin ./*tbeam-*/system-info.bin ./**/firmware*.bin ./**/*.uf2 ./**/*.elf ./**/meshtasticd_linux_amd64 ./*native*/*device-*.sh ./*native*/*device-*.bat
run: mv -b -t ./ ./*tbeam-1*/littlefs*.bin ./*tbeam-1*/bleota.bin ./**/firmware*.bin ./*t-echo*/Meshtastic_nRF52_factory_erase.uf2 ./**/firmware-*.uf2 ./**/*.elf ./**/meshtasticd_linux_amd64 ./*native*/*device-*.sh ./*native*/*device-*.bat
- name: Repackage in single firmware zip
uses: actions/upload-artifact@v2
@@ -322,6 +390,11 @@ jobs:
# For diagnostics
- name: Show artifacts
run: ls -lR
- name: Device scripts permissions
run: |
chmod +x ./output/device-install.sh
chmod +x ./output/device-update.sh
- name: Zip firmware
run: zip -j -r ./firmware-${{ steps.version.outputs.version }}.zip ./output
@@ -344,3 +417,89 @@ jobs:
artifacts-branch: device
artifacts-dir: pr
artifacts: ./firmware-${{ steps.version.outputs.version }}.zip
release-artifacts:
runs-on: ubuntu-latest
if: ${{ github.event_name == 'workflow_dispatch' }}
needs: [gather-artifacts, after-checks]
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup Python
uses: actions/setup-python@v2
with:
python-version: 3.x
- name: Get release version string
run: echo "::set-output name=version::$(./bin/buildinfo.py long)"
id: version
- uses: actions/download-artifact@v2
with:
name: firmware-${{ steps.version.outputs.version }}
path: ./output
- name: Device scripts permissions
run: |
chmod +x ./output/device-install.sh
chmod +x ./output/device-update.sh
- name: Zip firmware
run: zip -j -r ./firmware-${{ steps.version.outputs.version }}.zip ./output
- uses: actions/download-artifact@v2
with:
name: debug-elfs-${{ steps.version.outputs.version }}.zip
path: ./elfs
- name: Zip Elfs
run: zip -j -r ./debug-elfs-${{ steps.version.outputs.version }}.zip ./elfs
# For diagnostics
- name: Show artifacts
run: ls -lR
- name: Create release
uses: actions/create-release@v1
id: create_release
with:
draft: true
prerelease: true
release_name: Meshtastic Device ${{ steps.version.outputs.version }} alpha - Public Preview
tag_name: v${{ steps.version.outputs.version }}
body: |
Autogenerated by github action, developer should edit as required before publishing...
env:
GITHUB_TOKEN: ${{ github.token }}
- name: Add bins to release
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ github.token }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./firmware-${{ steps.version.outputs.version }}.zip
asset_name: firmware-${{ steps.version.outputs.version }}.zip
asset_content_type: application/zip
- name: Add debug elfs to release
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ github.token }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./debug-elfs-${{ steps.version.outputs.version }}.zip
asset_name: debug-elfs-${{ steps.version.outputs.version }}.zip
asset_content_type: application/zip
- name: Bump version.properties
run: >-
bin/bump_version.py
- name: Create version.properties pull request
uses: peter-evans/create-pull-request@v3
with:
add-paths: |
version.properties
-92
View File
@@ -1,92 +0,0 @@
name: Make Release
on:
# Can optionally take parameters from the github UI, more info here https://github.blog/changelog/2020-07-06-github-actions-manual-triggers-with-workflow_dispatch/#:~:text=You%20can%20now%20create%20workflows,the%20workflow%20is%20run%20on.
workflow_dispatch:
# inputs:
# Only want to run if version.properties is bumped in master
push:
branches:
- master
paths:
- "version.properties"
jobs:
release-build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
submodules: "recursive"
- name: Setup Python
uses: actions/setup-python@v2
with:
python-version: 3.x
# Will be available in steps.version.outputs.version
- name: Get release version string
run: echo "::set-output name=version::$(./bin/buildinfo.py long)"
id: version
# Note: we don't use caches on release builds because we don't want to accidentally not have a virgin build machine
- name: Upgrade python tools
# We actually want to run this every time
# if: steps.cache-pip.outputs.cache-hit != 'true'
run: |
python -m pip install --upgrade pip
pip install -U platformio meshtastic adafruit-nrfutil littlefs-python
- name: Upgrade platformio
run: |
pio upgrade
- name: Pull web ui
uses: dsaltares/fetch-gh-release-asset@master
with:
repo: "meshtastic/meshtastic-web"
file: "build.tar"
target: "build.tar"
token: ${{ secrets.GITHUB_TOKEN }}
- name: Unpack web ui
run: |
tar -xf build.tar -C data/static
rm build.tar
- name: Build everything
run: bin/build-all.sh
- name: Create release
uses: actions/create-release@v1
id: create_release
with:
draft: true
prerelease: true
release_name: ${{ steps.version.outputs.version }} alpha
tag_name: v${{ steps.version.outputs.version }}
body: |
Autogenerated by github action, developer should edit as required before publishing...
env:
GITHUB_TOKEN: ${{ github.token }}
- name: Add bins to release
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ github.token }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: release/archive/firmware-${{ steps.version.outputs.version }}.zip
asset_name: firmware-${{ steps.version.outputs.version }}.zip
asset_content_type: application/zip
- name: Add debug elfs to release
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ github.token }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: release/archive/elfs-${{ steps.version.outputs.version }}.zip
asset_name: debug-elfs-${{ steps.version.outputs.version }}.zip
asset_content_type: application/zip
+3 -3
View File
@@ -17,9 +17,9 @@ jobs:
- name: Download nanopb
run: |
wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.5-linux-x86.tar.gz
tar xvzf nanopb-0.4.5-linux-x86.tar.gz
mv nanopb-0.4.5-linux-x86 nanopb-0.4.5
wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.6-linux-x86.tar.gz
tar xvzf nanopb-0.4.6-linux-x86.tar.gz
mv nanopb-0.4.6-linux-x86 nanopb-0.4.6
- name: Re-generate protocol buffers
run: |
+4 -1
View File
@@ -51,7 +51,10 @@
"iterator": "cpp",
"shared_mutex": "cpp",
"iostream": "cpp",
"esp_nimble_hci.h": "c"
"esp_nimble_hci.h": "c",
"map": "cpp",
"random": "cpp",
"*.tpp": "cpp"
},
"cSpell.words": [
"Blox",
+53
View File
@@ -0,0 +1,53 @@
; Common settings for ESP targes, mixin with extends = esp32_base
[esp32_base]
extends = arduino_base
platform = espressif32@^5.2.0
build_src_filter =
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2040>
upload_speed = 921600
debug_init_break = tbreak setup
monitor_filters = esp32_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
-DAXP_DEBUG_PORT=Serial
-DCONFIG_BT_NIMBLE_ENABLED
-DCONFIG_NIMBLE_CPP_LOG_LEVEL=2
-DCONFIG_BT_NIMBLE_MAX_CCCDS=20
-DESP_OPENSSL_SUPPRESS_LEGACY_WARNING
lib_deps =
${arduino_base.lib_deps}
${networking_base.lib_deps}
${environmental_base.lib_deps}
https://github.com/meshtastic/esp32_https_server.git#657509856ce97e9dddeffb89a559f544faefd5cd
h2zero/NimBLE-Arduino@^1.4.0
arduino-libraries/NTPClient@^3.1.0
https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6
lib_ignore =
segger_rtt
ESP32 BLE Arduino
; leave this commented out to avoid breaking Windows
;upload_port = /dev/ttyUSB0
;monitor_port = /dev/ttyUSB0
; Please don't delete these lines. JM uses them.
;upload_port = /dev/cu.SLAB_USBtoUART
;monitor_port = /dev/cu.SLAB_USBtoUART
; customize the partition table
; http://docs.platformio.org/en/latest/platforms/espressif32.html#partition-tables
board_build.partitions = partition-table.csv
+46
View File
@@ -0,0 +1,46 @@
[esp32s3_base]
extends = arduino_base
platform = espressif32@^5.2.0
build_src_filter =
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2040>
upload_speed = 961200
monitor_speed = 115200
debug_init_break = tbreak setup
monitor_filters = esp32_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
-DAXP_DEBUG_PORT=Serial
-DCONFIG_BT_NIMBLE_ENABLED
-DCONFIG_NIMBLE_CPP_LOG_LEVEL=2
-DCONFIG_BT_NIMBLE_MAX_CCCDS=20
-DESP_OPENSSL_SUPPRESS_LEGACY_WARNING
lib_deps =
${arduino_base.lib_deps}
${networking_base.lib_deps}
${environmental_base.lib_deps}
https://github.com/meshtastic/esp32_https_server.git#657509856ce97e9dddeffb89a559f544faefd5cd
h2zero/NimBLE-Arduino@^1.4.0
arduino-libraries/NTPClient@^3.1.0
https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6
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
+20
View File
@@ -0,0 +1,20 @@
[nrf52_base]
; Instead of the standard nordicnrf52 platform, we use our fork which has our added variant files
; platform = nordicnrf52 ;pending https://github.com/platformio/builder-framework-arduino-nrf5/pull/7
platform = https://github.com/meshtastic/platform-nordicnrf52.git#merge
extends = arduino_base
build_type = debug ; I'm debugging with ICE a lot now
; note: liboberon provides the AES256 implementation for NRF52 (though not using the hardware acceleration of the NRF52840 - FIXME)
build_flags =
${arduino_base.build_flags} -Wno-unused-variable
-Isrc/platform/nrf52
build_src_filter =
${arduino_base.build_src_filter} -<platform/esp32/> -<platform/stm32wl> -<nimble/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mqtt/> -<platform/rp2040>
lib_ignore =
BluetoothOTA
; Note: By default no lora device is created for this build - it uses a simulated interface
[env:feather_nrf52832]
extends = nrf52_base
board = adafruit_feather_nrf52832
+14
View File
@@ -0,0 +1,14 @@
[nrf52840_base]
extends = nrf52_base
build_flags = ${nrf52_base.build_flags}
lib_deps =
${arduino_base.lib_deps}
${environmental_base.lib_deps}
https://github.com/Kongduino/Adafruit_nRFCrypto.git#20fc7fdaf086bd70e901c007dd23c6e8856aec25
; Note: By default no lora device is created for this build - it uses a simulated interface
[env:nrf52840dk]
extends = nrf52840_base
board = nrf52840_dk
+19
View File
@@ -0,0 +1,19 @@
; The Portduino based sim environment on top of any host OS, all hardware will be simulated
[portduino_base]
build_src_filter =
${env.build_src_filter}
-<platform/esp32/>
-<nimble/>
-<platform/nrf52/>
-<platform/stm32wl/>
-<platform/rp2040>
-<mesh/http/>
-<modules/esp32>
-<modules/Telemetry>
+<../variants/portduino>
lib_deps =
${env.lib_deps}
${networking_base.lib_deps}
rweather/Crypto@^0.4.0
https://github.com/meshtastic/RadioLib.git#5582ac30578ff3f53f20630a00b2a8a4b8f92c74
build_flags = ${arduino_base.build_flags} -Isrc/platform/portduino
+19
View File
@@ -0,0 +1,19 @@
; Common settings for rp2040 Processor based targets
[rp2040_base]
platform = https://github.com/maxgerhardt/platform-raspberrypi.git
extends = arduino_base
board_build.core = earlephilhower
board_build.filesystem_size = 0.5m
build_flags =
${arduino_base.build_flags} -Wno-unused-variable
-Isrc/platform/rp2040
-D__PLAT_RP2040__
# -D _POSIX_THREADS
build_src_filter =
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mqtt/> -<platform/nrf52/> -<platform/stm32wl>
lib_ignore =
BluetoothOTA
lib_deps =
${arduino_base.lib_deps}
${environmental_base.lib_deps}
https://github.com/kokke/tiny-AES-c.git#f06ac37fc31dfdaca2e0d9bec83f90d5663c319b
+18
View File
@@ -0,0 +1,18 @@
[stm32wl5e_base]
platform = ststm32
board = generic_wl5e
framework = arduino
build_type = debug
build_flags =
${arduino_base.build_flags}
-Isrc/platform/stm32wl -g
-DHAL_SUBGHZ_MODULE_ENABLED
# Arduino/PlatformIO framework-arduinoststm32 package does not presently have SUBGHZSPI support
# -DPIN_SPI_MOSI=PINSUBGHZSPIMOSI -DPIN_SPI_MISO=PINSUBGHZSPIMISO -DPIN_SPI_SCK=PINSUBGHZSPISCK
build_src_filter =
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mqtt/> -<graphics> -<input> -<buzz> -<modules/Telemetry> -<platform/nrf52> -<platform/portduino> -<platform/rp2040>
lib_deps =
${env.lib_deps}
https://github.com/kokke/tiny-AES-c.git#f06ac37fc31dfdaca2e0d9bec83f90d5663c319b
lib_ignore =
mathertel/OneButton@^2.0.3
Binary file not shown.
+1 -1
View File
@@ -5,7 +5,7 @@ set -e
VERSION=`bin/buildinfo.py long`
SHORT_VERSION=`bin/buildinfo.py short`
BOARDS_ESP32="rak11200 tlora-v2 tlora-v1 tlora_v1_3 tlora-v2-1-1.6 tbeam heltec-v1 heltec-v2.0 heltec-v2.1 tbeam0.7 meshtastic-diy-v1 nano-g1"
BOARDS_ESP32="rak11200 tlora-v2 tlora-v1 tlora_v1_3 tlora-v2-1-1.6 tbeam heltec-v1 heltec-v2.0 heltec-v2.1 tbeam0.7 meshtastic-diy-v1 nano-g1 station-g1 m5stack-core m5stack-coreink"
#BOARDS_ESP32=tbeam
# FIXME note nrf52840dk build is for some reason only generating a BIN file but not a HEX file nrf52840dk-geeksville is fine
+2 -4
View File
@@ -29,13 +29,11 @@ SRCELF=.pio/build/$1/firmware.elf
cp $SRCELF $OUTDIR/$basename.elf
echo "Copying ESP32 bin file"
SRCBIN=.pio/build/$1/firmware.bin
SRCBIN=.pio/build/$1/firmware.factory.bin
cp $SRCBIN $OUTDIR/$basename.bin
echo "Building Filesystem for ESP32 targets"
pio run --environment tbeam -t buildfs
cp .pio/build/tbeam/spiffs.bin $OUTDIR/littlefs-$VERSION.bin
cp images/system-info.bin $OUTDIR/system-info.bin
cp .pio/build/tbeam/littlefs.bin $OUTDIR/littlefs-$VERSION.bin
cp bin/device-install.* $OUTDIR
cp bin/device-update.* $OUTDIR
+1
View File
@@ -34,3 +34,4 @@ bin/uf2conv.py $SRCHEX -c -o $OUTDIR/$basename.uf2 -f 0xADA52840
cp bin/device-install.* $OUTDIR
cp bin/device-update.* $OUTDIR
cp bin/*.uf2 $OUTDIR
+36
View File
@@ -0,0 +1,36 @@
#!/usr/bin/env bash
set -e
VERSION=`bin/buildinfo.py long`
SHORT_VERSION=`bin/buildinfo.py short`
OUTDIR=release/
rm -f $OUTDIR/firmware*
rm -r $OUTDIR/* || true
# Make sure our submodules are current
git submodule update
# Important to pull latest version of libs into all device flavors, otherwise some devices might be stale
platformio lib update
echo "Building for $1 with $PLATFORMIO_BUILD_FLAGS"
rm -f .pio/build/$1/firmware.*
# The shell vars the build tool expects to find
export APP_VERSION=$VERSION
basename=firmware-$1-$VERSION
pio run --environment $1 # -v
SRCELF=.pio/build/$1/firmware.elf
cp $SRCELF $OUTDIR/$basename.elf
echo "Copying uf2 file"
SRCBIN=.pio/build/$1/firmware.uf2
cp $SRCBIN $OUTDIR/$basename.uf2
cp bin/device-install.* $OUTDIR
cp bin/device-update.* $OUTDIR
+16
View File
@@ -0,0 +1,16 @@
#!/usr/bin/env python
"""Bump the version number"""
lines = None
with open('version.properties', 'r', encoding='utf-8') as f:
lines = f.readlines()
with open('version.properties', 'w', encoding='utf-8') as f:
for line in lines:
if line.lstrip().startswith("build = "):
words = line.split(" = ")
ver = f'build = {int(words[1]) + 1}'
f.write(f'{ver}\n')
else:
f.write(line)
+23
View File
@@ -0,0 +1,23 @@
#!/usr/bin/env bash
# Note: This is a prototype for how we could add static code analysis to the CI.
set -e
if [[ $# -gt 0 ]]; then
# can override which environment by passing arg
BOARDS="$@"
else
BOARDS="rak4631 rak4631_eink t-echo pca10059_diy_eink pico rak11200 tlora-v2 tlora-v1 tlora_v1_3 tlora-v2-1-1.6 tbeam heltec-v1 heltec-v2.0 heltec-v2.1 tbeam0.7 meshtastic-diy-v1 nano-g1 station-g1 m5stack-core m5stack-coreink tbeam-s3-core"
fi
echo "BOARDS:${BOARDS}"
CHECK=""
for BOARD in $BOARDS; do
CHECK="${CHECK} -e ${BOARD}"
done
echo $CHECK
pio pkg outdated -e $CHECK
Regular → Executable
+5 -5
View File
@@ -28,15 +28,15 @@ IF "__%FILENAME%__" == "____" (
)
IF EXIST %FILENAME% (
echo Trying to flash update %FILENAME%, but first erasing and writing system information"
%PYTHON% -m esptool --baud 921600 erase_flash
%PYTHON% -m esptool --baud 921600 write_flash 0x1000 system-info.bin
%PYTHON% -m esptool --baud 115200 erase_flash
%PYTHON% -m esptool --baud 115200 write_flash 0x00 %FILENAME%
%PYTHON% -m esptool --baud 115200 write_flash 0x260000 bleota.bin
for %%f in (littlefs-*.bin) do (
%PYTHON% -m esptool --baud 921600 write_flash 0x00390000 %%f
%PYTHON% -m esptool --baud 115200 write_flash 0x300000 %%f
)
%PYTHON% -m esptool --baud 921600 write_flash 0x10000 %FILENAME%
) else (
echo "Invalid file: %FILENAME%"
goto HELP
)
:EOF
:EOF
+4 -3
View File
@@ -47,9 +47,10 @@ shift "$((OPTIND-1))"
if [ -f "${FILENAME}" ]; then
echo "Trying to flash ${FILENAME}, but first erasing and writing system information"
"$PYTHON" -m esptool erase_flash
"$PYTHON" -m esptool write_flash 0x1000 system-info.bin
"$PYTHON" -m esptool write_flash 0x00390000 littlefs-*.bin
"$PYTHON" -m esptool write_flash 0x10000 ${FILENAME}
"$PYTHON" -m esptool write_flash 0x00 ${FILENAME}
"$PYTHON" -m esptool write_flash 0x260000 bleota.bin
"$PYTHON" -m esptool write_flash 0x300000 littlefs-*.bin
else
echo "Invalid file: ${FILENAME}"
show_help
Regular → Executable
+2 -4
View File
@@ -28,12 +28,10 @@ IF "__%FILENAME%__" == "____" (
)
IF EXIST %FILENAME% (
echo Trying to flash update %FILENAME%
%PYTHON% -m esptool --baud 921600 write_flash 0x10000 %FILENAME%
echo Erasing the otadata partition, which will turn off flash flippy-flop and force the first image to be used
%PYTHON% -m esptool --baud 921600 erase_region 0xe000 0x2000
%PYTHON% -m esptool --baud 115200 write_flash 0x00 %FILENAME%
) else (
echo "Invalid file: %FILENAME%"
goto HELP
)
:EOF
:EOF
+1 -3
View File
@@ -44,9 +44,7 @@ shift "$((OPTIND-1))"
if [ -f "${FILENAME}" ]; then
echo "Trying to flash update ${FILENAME}."
$PYTHON -m esptool --baud 921600 write_flash 0x10000 ${FILENAME}
echo "Erasing the otadata partition, which will turn off flash flippy-flop and force the first image to be used"
$PYTHON -m esptool --baud 921600 erase_region 0xe000 0x2000
$PYTHON -m esptool --baud 115200 write_flash 0x00 ${FILENAME}
else
echo "Invalid file: ${FILENAME}"
show_help
-51
View File
@@ -1,51 +0,0 @@
#!/usr/bin/env python3
import getopt
import sys
import os
from littlefs import LittleFS
from pathlib import Path
print( "Building LittleFS image..." )
argList = sys.argv[1:]
arxx = { argList[i]: argList[i+1] for i in range(0, len(argList)-1, 2) }
dataPath = arxx["-c"]
blockSize = int(arxx["-b"])
blockCount = int(arxx["-s"]) / blockSize
cwd = os.getcwd()
os.chdir(dataPath)
fileList = []
dirList = []
for (dirpath, dirnames, filenames) in os.walk('.'):
for f in filenames:
if (f[:1] != '.'):
fileList.append( os.path.join(dirpath, f) )
for d in dirnames:
if (d[:1] != '.'):
dirList.append( os.path.join(dirpath, d) )
fs = LittleFS(block_size=blockSize, block_count=blockCount) # create a 448kB partition
for curDir in dirList:
print( "Creating dir " + curDir )
fs.mkdir( curDir )
for curFile in fileList:
print( "Adding file " + curFile )
with open( curFile, 'rb' ) as f:
data = f.read()
with fs.open( curFile, 'wb') as fh:
fh.write( data )
outName = argList[-1]
os.chdir(cwd)
with open(outName, 'wb') as fh:
fh.write(fs.context.buffer)
+55 -9
View File
@@ -1,24 +1,70 @@
import subprocess
import configparser
import traceback
import sys
from os.path import join
from readprops import readProps
Import("env")
env.Replace( MKSPIFFSTOOL=env.get("PROJECT_DIR") + '/bin/mklittlefs.py' )
try:
import littlefs
except ImportError:
env.Execute("$PYTHONEXE -m pip install littlefs-python")
platform = env.PioPlatform()
def esp32_create_combined_bin(source, target, env):
# this sub is borrowed from ESPEasy build toolchain. It's licensed under GPL V3
# https://github.com/letscontrolit/ESPEasy/blob/mega/tools/pio/post_esp32.py
print("Generating combined binary for serial flashing")
app_offset = 0x10000
new_file_name = env.subst("$BUILD_DIR/${PROGNAME}.factory.bin")
sections = env.subst(env.get("FLASH_EXTRA_IMAGES"))
firmware_name = env.subst("$BUILD_DIR/${PROGNAME}.bin")
chip = env.get("BOARD_MCU")
flash_size = env.BoardConfig().get("upload.flash_size")
flash_freq = env.BoardConfig().get("build.f_flash", '40m')
flash_freq = flash_freq.replace('000000L', 'm')
flash_mode = env.BoardConfig().get("build.flash_mode", "dio")
memory_type = env.BoardConfig().get("build.arduino.memory_type", "qio_qspi")
if flash_mode == "qio" or flash_mode == "qout":
flash_mode = "dio"
if memory_type == "opi_opi" or memory_type == "opi_qspi":
flash_mode = "dout"
cmd = [
"--chip",
chip,
"merge_bin",
"-o",
new_file_name,
"--flash_mode",
flash_mode,
"--flash_freq",
flash_freq,
"--flash_size",
flash_size,
]
print(" Offset | File")
for section in sections:
sect_adr, sect_file = section.split(" ", 1)
print(f" - {sect_adr} | {sect_file}")
cmd += [sect_adr, sect_file]
print(f" - {hex(app_offset)} | {firmware_name}")
cmd += [hex(app_offset), firmware_name]
print('Using esptool.py arguments: %s' % ' '.join(cmd))
esptool.main(cmd)
if (platform.name == "espressif32"):
sys.path.append(join(platform.get_package_dir("tool-esptoolpy")))
import esptool
env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", esp32_create_combined_bin)
Import("projenv")
prefsLoc = projenv["PROJECT_DIR"] + "/version.properties"
verObj = readProps(prefsLoc)
print("Using meshtastic platform-custom.py, firmare version " + verObj['long'])
# print("path is" + ','.join(sys.path))
print("Using meshtastic platformio-custom.py, firmware version " + verObj['long'])
# General options that are passed to the C and C++ compilers
projenv.Append(CCFLAGS=[
+1 -1
View File
@@ -1,3 +1,3 @@
#!/usr/bin/env bash
esptool.py --baud 921600 read_flash 0x1000 0xf000 system-info.img
esptool.py --baud 115200 read_flash 0x1000 0xf000 system-info.img
+1 -1
View File
@@ -32,6 +32,6 @@ def readProps(prefsLoc):
# traceback.print_exc()
verObj['long'] = verObj['short']
# print("firmare version " + verStr)
# print("firmware version " + verStr)
return verObj
# print("path is" + ','.join(sys.path))
+1 -1
View File
@@ -1 +1 @@
cd protobufs && ..\nanopb-0.4.5\generator-bin\protoc.exe --nanopb_out=-v:..\src\mesh\generated -I=..\protobufs *.proto
cd protobufs && ..\nanopb-0.4.6\generator-bin\protoc.exe --nanopb_out=-v:..\src\mesh\generated -I=..\protobufs *.proto
+3 -3
View File
@@ -2,13 +2,13 @@
set -e
echo "This script requires https://jpa.kapsi.fi/nanopb/download/ version 0.4.5 to be located in the"
echo "This script requires https://jpa.kapsi.fi/nanopb/download/ version 0.4.6 to be located in the"
echo "meshtastic-device root directory if the following step fails, you should download the correct"
echo "prebuilt binaries for your computer into nanopb-0.4.5"
echo "prebuilt binaries for your computer into nanopb-0.4.6"
# the nanopb tool seems to require that the .options file be in the current directory!
cd protobufs
../nanopb-0.4.5/generator-bin/protoc --nanopb_out=-v:../src/mesh/generated -I=../protobufs *.proto
../nanopb-0.4.6/generator-bin/protoc --nanopb_out=-v:../src/mesh/generated -I=../protobufs *.proto
#echo "Regenerating protobuf documentation - if you see an error message"
#echo "you can ignore it unless doing a new protobuf release to github."
+31
View File
@@ -0,0 +1,31 @@
{
"build": {
"core": "stm32",
"cpu": "cortex-m4",
"extra_flags": "-DSTM32WLxx -DSTM32WLE5xx -DARDUINO_GENERIC_WLE5CCUX",
"f_cpu": "48000000L",
"mcu": "stm32wle5ccu",
"variant": "STM32WLxx/WL54CCU_WL55CCU_WLE4C(8-B-C)U_WLE5C(8-B-C)U",
"product_line": "STM32WLE5xx"
},
"debug": {
"default_tools": [
"stlink"
],
"jlink_device": "STM32WLE5CC",
"openocd_target": "stm32wlx",
"svd_path": "STM32WLE5_CM4.svd"
},
"frameworks": ["arduino"],
"name": "BB-STM32WL",
"upload": {
"maximum_ram_size": 65536,
"maximum_size": 262144,
"protocol": "cmsis-dap",
"protocols": [
"cmsis-dap"
]
},
"url": "https://www.st.com/en/microcontrollers-microprocessors/stm32wl-series.html",
"vendor": "ST"
}
+48
View File
@@ -0,0 +1,48 @@
{
"build": {
"arduino":{
"ldscript": "esp32s3_out.ld"
},
"core": "esp32",
"extra_flags": [
"-DBOARD_HAS_PSRAM",
"-DLILYGO_TBEAM_S3_CORE",
"-DARDUINO_USB_CDC_ON_BOOT=1",
"-DARDUINO_USB_DFU_ON_BOOT=1",
"-DARDUINO_USB_MSC_ON_BOOT=1",
"-DARDUINO_USB_MODE=1",
"-DARDUINO_RUNNING_CORE=1",
"-DARDUINO_EVENT_RUNNING_CORE=1"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "dio",
"hwids": [
[
"0X303A",
"0x1001"
]
],
"mcu": "esp32s3",
"variant": "tbeam-s3-core"
},
"connectivity": [
"wifi"
],
"debug": {
"openocd_target": "esp32s3.cfg"
},
"frameworks": [
"arduino"
],
"name": "LilyGo TBeam-S3-Core",
"upload": {
"flash_size": "8MB",
"maximum_ram_size": 327680,
"maximum_size": 8388608,
"require_upload_port": true,
"speed": 921600
},
"url": "http://www.lilygo.cn/",
"vendor": "LilyGo"
}
Binary file not shown.
+5 -5
View File
@@ -1,8 +1,8 @@
# FIXME! using the genpartitions based table doesn't work on TTGO so for now I stay with my old memory map
# This is a layout for 4MB of flash
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x1c0000,
app1, app, ota_1, 0x1d0000,0x1c0000,
spiffs, data, spiffs, 0x390000,0x070000,
nvs, data, nvs, 0x009000, 0x005000,
otadata, data, ota, 0x00e000, 0x002000,
app, app, ota_0, 0x010000, 0x250000,
flashApp, app, ota_1, 0x260000, 0x0A0000,
spiffs, data, spiffs, 0x300000, 0x100000,
1 # FIXME! using the genpartitions based table doesn't work on TTGO so for now I stay with my old memory map
2 # This is a layout for 4MB of flash
3 # Name, Type, SubType, Offset, Size, Flags
4 nvs, data, nvs, 0x9000, 0x5000, nvs, data, nvs, 0x009000, 0x005000,
5 otadata, data, ota, 0xe000, 0x2000, otadata, data, ota, 0x00e000, 0x002000,
6 app0, app, ota_0, 0x10000, 0x1c0000, app, app, ota_0, 0x010000, 0x250000,
7 app1, app, ota_1, 0x1d0000,0x1c0000, flashApp, app, ota_1, 0x260000, 0x0A0000,
8 spiffs, data, spiffs, 0x390000,0x070000, spiffs, data, spiffs, 0x300000, 0x100000,
+29 -93
View File
@@ -3,6 +3,7 @@
[platformio]
default_envs = tbeam
;default_envs = tbeam-s3-core
;default_envs = tbeam0.7
;default_envs = heltec-v1
;default_envs = heltec-v2.0
@@ -20,8 +21,12 @@ default_envs = tbeam
;default_envs = pca10059_diy_eink
;default_envs = meshtastic-diy-v1
;default_envs = meshtastic-diy-v1.1
;default_envs = m5stack-coreink
;default_envs = rak4631
extra_configs = variants/*/platformio.ini
extra_configs =
arch/*/*.ini
variants/*/platformio.ini
[env]
extra_scripts = bin/platformio-custom.py
@@ -37,22 +42,16 @@ build_flags = -Wno-missing-field-initializers
-DTINYGPS_OPTION_NO_CUSTOM_FIELDS
-DPB_ENABLE_MALLOC=1
monitor_speed = 921600
monitor_speed = 115200
lib_deps =
https://github.com/meshtastic/esp8266-oled-ssd1306.git#53580644255b48ebb7a737343c6b4e71c7e11cf2 ; ESP8266_SSD1306
mathertel/OneButton@^2.0.3 ; OneButton library for non-blocking button debounce
1202 ; CRC32, explicitly needed because dependency is missing in the ble ota update lib
https://github.com/meshtastic/arduino-fsm.git
https://github.com/meshtastic/RadioLib.git#5582ac30578ff3f53f20630a00b2a8a4b8f92c74
https://github.com/meshtastic/TinyGPSPlus.git
https://github.com/meshtastic/AXP202X_Library.git#8404abb6d4b486748636bc6ad72d2a47baaf5460
Wire ; explicitly needed here because the AXP202 library forgets to add it
SPI
https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159
https://github.com/meshtastic/TinyGPSPlus.git#2f0d0528d737000043e949f4c3bdfb623cf0b902
https://github.com/meshtastic/ArduinoThread.git#72921ac222eed6f526ba1682023cee290d9aa1b3
PubSubClient
nanopb/Nanopb@^0.4.6
meshtastic/json11@^1.0.2
erriez/ErriezCRC32@^1.0.1
; Used for the code analysis in PIO Home / Inspect
check_tool = cppcheck
@@ -63,93 +62,30 @@ check_skip_packages = yes
framework = arduino
lib_deps =
${env.lib_deps}
build_flags = ${env.build_flags} -Os
# -DRADIOLIB_GODMODE
build_src_filter = ${env.build_src_filter} -<portduino/>
; Portduino is using meshtastic fork for now
jgromes/RadioLib@5.4.1
; Common libs for environmental measurements (not included in native / portduino)
[environmental]
build_flags = ${env.build_flags} -Os
-DRADIOLIB_SPI_PARANOID=0
# -DRADIOLIB_GODMODE
build_src_filter = ${env.build_src_filter} -<platform/portduino/>
; Common libs for communicating over TCP/IP networks such as MQTT
[networking_base]
lib_deps =
knolleary/PubSubClient@^2.8
meshtastic/json11@^1.0.2
; Common libs for environmental measurements in telemetry module
; (not included in native / portduino)
[environmental_base]
lib_deps =
adafruit/Adafruit BusIO@^1.11.4
adafruit/DHT sensor library@^1.4.1
adafruit/Adafruit Unified Sensor@^1.1.4
paulstoffregen/OneWire@^2.3.5
robtillaart/DS18B20@^0.1.11
adafruit/Adafruit BMP280 Library@^2.6.6
adafruit/Adafruit BME280 Library@^2.2.2
adafruit/Adafruit BME680 Library@^2.0.1
adafruit/Adafruit MCP9808 Library@^2.0.0
adafruit/Adafruit INA260 Library@^1.5.0
adafruit/Adafruit INA219@^1.2.0
; Common settings for ESP targes, mixin with extends = esp32_base
[esp32_base]
extends = arduino_base
platform = espressif32@3.5.0
build_src_filter =
${arduino_base.build_src_filter} -<nrf52/>
upload_speed = 921600
debug_init_break = tbreak setup
# Remove -DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL for low level BLE logging.
# See library directory for BLE logging possible values: .pio/libdeps/tbeam/NimBLE-Arduino/src/log_common/log_common.h
# This overrides the BLE logging default of LOG_LEVEL_INFO (1) from: .pio/libdeps/tbeam/NimBLE-Arduino/src/esp_nimble_cfg.h
# -DUSE_NEW_ESP32_BLUETOOTH will enable the new NimBLE C++ api
build_flags =
${arduino_base.build_flags} -Wall -Wextra -Isrc/esp32 -Isrc/esp32-mfix-esp32-psram-cache-issue -lnimble -std=c++11
-DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG -DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL
-DAXP_DEBUG_PORT=Serial -DUSE_NEW_ESP32_BLUETOOTH
lib_deps =
${arduino_base.lib_deps}
${environmental.lib_deps}
https://github.com/meshtastic/esp32_https_server.git
h2zero/NimBLE-Arduino@1.3.7
arduino-libraries/NTPClient@^3.1.0
lorol/LittleFS_esp32@^1.0.6
lib_ignore =
segger_rtt
ESP32 BLE Arduino
platform_packages =
framework-arduinoespressif32@https://github.com/meshtastic/arduino-esp32.git#4cde0f5d412d2695184f32e8a47e9bea57b45276
; leave this commented out to avoid breaking Windows
;upload_port = /dev/ttyUSB0
;monitor_port = /dev/ttyUSB0
; Please don't delete these lines. JM uses them.
;upload_port = /dev/cu.SLAB_USBtoUART
;monitor_port = /dev/cu.SLAB_USBtoUART
; customize the partition table
; http://docs.platformio.org/en/latest/platforms/espressif32.html#partition-tables
board_build.partitions = partition-table.csv
[nrf52_base]
; Instead of the standard nordicnrf52 platform, we use our fork which has our added variant files
; platform = nordicnrf52 ;pending https://github.com/platformio/builder-framework-arduino-nrf5/pull/7
platform = https://github.com/meshtastic/platform-nordicnrf52.git#merge
extends = arduino_base
build_type = debug ; I'm debugging with ICE a lot now
; note: liboberon provides the AES256 implementation for NRF52 (though not using the hardware acceleration of the NRF52840 - FIXME)
build_flags =
${arduino_base.build_flags} -Wno-unused-variable
-Isrc/nrf52
build_src_filter =
${arduino_base.build_src_filter} -<esp32/> -<nimble/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mqtt/>
lib_ignore =
BluetoothOTA
[nrf52840_base]
extends = nrf52_base
build_flags = ${nrf52_base.build_flags}
lib_deps =
${arduino_base.lib_deps}
${environmental.lib_deps}
https://github.com/Kongduino/Adafruit_nRFCrypto.git
; Note: By default no lora device is created for this build - it uses a simulated interface
[env:nrf52840dk]
extends = nrf52840_base
board = nrf52840_dk
; Note: By default no lora device is created for this build - it uses a simulated interface
[env:feather_nrf52832]
extends = nrf52_base
board = adafruit_feather_nrf52832
+15 -12
View File
@@ -7,10 +7,6 @@
#include "power.h"
#include <OneButton.h>
#ifndef NO_ESP32
#include "nimble/BluetoothUtil.h"
#endif
namespace concurrency
{
/**
@@ -127,25 +123,32 @@ class ButtonThread : public concurrency::OSThread
static void userButtonPressedLong()
{
// DEBUG_MSG("Long press!\n");
#ifndef NRF52_SERIES
#ifdef ARCH_ESP32
screen->adjustBrightness();
#endif
// If user button is held down for 5 seconds, shutdown the device.
if ((millis() - longPressTime > 5 * 1000) && (longPressTime > 0)) {
#ifdef TBEAM_V10
if (axp192_found == true) {
#ifdef HAS_PMU
if (pmu_found == true) {
setLed(false);
power->shutdown();
}
#elif NRF52_SERIES
#elif defined(ARCH_NRF52)
// Do actual shutdown when button released, otherwise the button release
// may wake the board immediatedly.
if ((!shutdown_on_long_stop) && (millis() > 30 * 1000)) {
screen->startShutdownScreen();
DEBUG_MSG("Shutdown from long press");
playBeep();
#ifdef PIN_LED1
ledOff(PIN_LED1);
#endif
#ifdef PIN_LED2
ledOff(PIN_LED2);
#endif
#ifdef PIN_LED3
ledOff(PIN_LED3);
#endif
shutdown_on_long_stop = true;
}
#endif
@@ -156,19 +159,19 @@ class ButtonThread : public concurrency::OSThread
static void userButtonDoublePressed()
{
#ifndef NO_ESP32
#ifdef ARCH_ESP32
disablePin();
#elif defined(HAS_EINK)
#elif defined(USE_EINK)
digitalWrite(PIN_EINK_EN, digitalRead(PIN_EINK_EN) == LOW);
#endif
}
static void userButtonMultiPressed()
{
#ifndef NO_ESP32
#ifdef ARCH_ESP32
clearNVS();
#endif
#ifdef NRF52_SERIES
#ifdef ARCH_NRF52
clearBonds();
#endif
}
+1 -24
View File
@@ -10,36 +10,13 @@
#ifdef CONSOLE_MAX_BAUD
#define SERIAL_BAUD CONSOLE_MAX_BAUD
#else
#define SERIAL_BAUD 921600 // Serial debug baud rate
#define SERIAL_BAUD 115200 // Serial debug baud rate
#endif
#include "SerialConsole.h"
#define DEBUG_PORT (*console) // Serial debug port
// What platforms should use SEGGER?
#ifdef NRF52_SERIES
// Always include the SEGGER code on NRF52 - because useful for debugging
#include "SEGGER_RTT.h"
// The channel we send stdout data to
#define SEGGER_STDOUT_CH 0
// Debug printing to segger console
#define SEGGER_MSG(...) SEGGER_RTT_printf(SEGGER_STDOUT_CH, __VA_ARGS__)
// If we are not on a NRF52840 (which has built in USB-ACM serial support) and we don't have serial pins hooked up, then we MUST
// use SEGGER for debug output
#if !defined(PIN_SERIAL_RX) && !defined(NRF52840_XXAA)
// No serial ports on this board - ONLY use segger in memory console
#define USE_SEGGER
#endif
#else
#define SERIAL0_RX_GPIO 3 // Always GPIO3 on ESP32
#endif
#ifdef USE_SEGGER
#define DEBUG_MSG(...) SEGGER_RTT_printf(0, __VA_ARGS__)
#else
+136 -8
View File
@@ -1,10 +1,58 @@
#include "configuration.h"
#include "FSCommon.h"
void listDir(const char * dirname, uint8_t levels)
#ifdef FSCom
bool copyFile(const char* from, const char* to)
{
File root = FSCom.open(dirname);
#ifdef FSCom
unsigned char cbuffer[16];
File f1 = FSCom.open(from, FILE_O_READ);
if (!f1){
DEBUG_MSG("Failed to open source file %s\n", from);
return false;
}
File f2 = FSCom.open(to, FILE_O_WRITE);
if (!f2) {
DEBUG_MSG("Failed to open destination file %s\n", to);
return false;
}
while (f1.available() > 0) {
byte i = f1.read(cbuffer, 16);
f2.write(cbuffer, i);
}
f2.close();
f1.close();
return true;
#endif
}
bool renameFile(const char* pathFrom, const char* pathTo)
{
#ifdef FSCom
#ifdef ARCH_ESP32
// rename was fixed for ESP32 IDF LittleFS in April
return FSCom.rename(pathFrom, pathTo);
#else
if (copyFile(pathFrom, pathTo) && FSCom.remove(pathFrom) ) {
return true;
} else{
return false;
}
#endif
#endif
}
void listDir(const char * dirname, uint8_t levels, boolean del = false)
{
#ifdef FSCom
#if (defined(ARCH_ESP32) || defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
char buffer[255];
#endif
File root = FSCom.open(dirname, FILE_O_READ);
if(!root){
return;
}
@@ -16,15 +64,92 @@ void listDir(const char * dirname, uint8_t levels)
while(file){
if(file.isDirectory() && !String(file.name()).endsWith(".")) {
if(levels){
listDir(file.name(), levels -1);
#ifdef ARCH_ESP32
listDir(file.path(), levels -1, del);
if(del) {
DEBUG_MSG("Removing %s\n", file.path());
strcpy(buffer, file.path());
file.close();
FSCom.rmdir(buffer);
} else {
file.close();
}
#elif (defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
listDir(file.name(), levels -1, del);
if(del) {
DEBUG_MSG("Removing %s\n", file.name());
strcpy(buffer, file.name());
file.close();
FSCom.rmdir(buffer);
} else {
file.close();
}
#else
listDir(file.name(), levels -1, del);
file.close();
#endif
}
} else {
DEBUG_MSG(" %s (%i Bytes)\n", file.name(), file.size());
#ifdef ARCH_ESP32
if(del) {
DEBUG_MSG("Deleting %s\n", file.path());
strcpy(buffer, file.path());
file.close();
FSCom.remove(buffer);
} else {
DEBUG_MSG(" %s (%i Bytes)\n", file.path(), file.size());
file.close();
}
#elif (defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
if(del) {
DEBUG_MSG("Deleting %s\n", file.name());
strcpy(buffer, file.name());
file.close();
FSCom.remove(buffer);
} else {
DEBUG_MSG(" %s (%i Bytes)\n", file.name(), file.size());
file.close();
}
#else
DEBUG_MSG(" %s (%i Bytes)\n", file.name(), file.size());
file.close();
#endif
}
file.close();
file = root.openNextFile();
}
file.close();
#ifdef ARCH_ESP32
if(del) {
DEBUG_MSG("Removing %s\n", root.path());
strcpy(buffer, root.path());
root.close();
FSCom.rmdir(buffer);
} else {
root.close();
}
#elif (defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
if(del) {
DEBUG_MSG("Removing %s\n", root.name());
strcpy(buffer, root.name());
root.close();
FSCom.rmdir(buffer);
} else {
root.close();
}
#else
root.close();
#endif
#endif
}
void rmDir(const char * dirname)
{
#ifdef FSCom
#if (defined(ARCH_ESP32) || defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
listDir(dirname, 10, true);
#elif defined(ARCH_NRF52)
// nRF52 implementation of LittleFS has a recursive delete function
FSCom.rmdir_r(dirname);
#endif
#endif
}
@@ -36,8 +161,11 @@ void fsInit()
DEBUG_MSG("ERROR filesystem mount Failed. Formatting...\n");
assert(0); // FIXME - report failure to phone
}
#ifdef ARCH_ESP32
DEBUG_MSG("Filesystem files (%d/%d Bytes):\n", FSCom.usedBytes(), FSCom.totalBytes());
#else
DEBUG_MSG("Filesystem files:\n");
#endif
listDir("/", 10);
#endif
}
+23 -6
View File
@@ -4,21 +4,34 @@
// Cross platform filesystem API
#ifdef PORTDUINO
#if defined(ARCH_PORTDUINO)
// Portduino version
#include "PortduinoFS.h"
#define FSCom PortduinoFS
#define FSBegin() true
#define FILE_O_WRITE "w"
#define FILE_O_READ "r"
#elif !defined(NO_ESP32)
#endif
#if defined(ARCH_RP2040)
// RP2040
#include "LittleFS.h"
#define FSCom LittleFS
#define FSBegin() FSCom.begin()
#define FILE_O_WRITE "w"
#define FILE_O_READ "r"
#endif
#if defined(ARCH_ESP32)
// ESP32 version
#include "LITTLEFS.h"
#define FSCom LITTLEFS
#include "LittleFS.h"
#define FSCom LittleFS
#define FSBegin() FSCom.begin(true)
#define FILE_O_WRITE "w"
#define FILE_O_READ "r"
#else
#endif
#if defined(ARCH_NRF52)
// NRF52 version
#include "InternalFileSystem.h"
#define FSCom InternalFS
@@ -26,4 +39,8 @@
using namespace Adafruit_LittleFS_Namespace;
#endif
void fsInit();
void fsInit();
bool copyFile(const char* from, const char* to);
bool renameFile(const char* pathFrom, const char* pathTo);
void listDir(const char * dirname, uint8_t levels, boolean del);
void rmDir(const char * dirname);
+18 -17
View File
@@ -25,21 +25,21 @@ class GPSStatus : public Status
public:
GPSStatus() { statusType = STATUS_TYPE_GPS; }
// proposed for deprecation
GPSStatus(bool hasLock, bool isConnected, int32_t latitude, int32_t longitude, int32_t altitude, uint32_t dop,
uint32_t heading, uint32_t numSatellites)
: Status()
{
this->hasLock = hasLock;
this->isConnected = isConnected;
// // proposed for deprecation
// GPSStatus(bool hasLock, bool isConnected, int32_t latitude, int32_t longitude, int32_t altitude, uint32_t dop,
// uint32_t heading, uint32_t numSatellites)
// : Status()
// {
// this->hasLock = hasLock;
// this->isConnected = isConnected;
this->p.latitude_i = latitude;
this->p.longitude_i = longitude;
this->p.altitude = altitude;
this->p.PDOP = dop;
this->p.ground_track = heading;
this->p.sats_in_view = numSatellites;
}
// this->p.latitude_i = latitude;
// this->p.longitude_i = longitude;
// this->p.altitude = altitude;
// this->p.PDOP = dop;
// this->p.ground_track = heading;
// this->p.sats_in_view = numSatellites;
// }
// preferred method
GPSStatus(bool hasLock, bool isConnected, const Position &pos) : Status()
@@ -114,6 +114,7 @@ class GPSStatus : public Status
newStatus->p.latitude_i != p.latitude_i || newStatus->p.longitude_i != p.longitude_i ||
newStatus->p.altitude != p.altitude || newStatus->p.altitude_hae != p.altitude_hae ||
newStatus->p.PDOP != p.PDOP || newStatus->p.ground_track != p.ground_track ||
newStatus->p.ground_speed != p.ground_speed ||
newStatus->p.sats_in_view != p.sats_in_view);
}
@@ -122,7 +123,7 @@ class GPSStatus : public Status
// Only update the status if values have actually changed
bool isDirty = matches(newStatus);
if (isDirty && p.pos_timestamp && (newStatus->p.pos_timestamp == p.pos_timestamp)) {
if (isDirty && p.timestamp && (newStatus->p.timestamp == p.timestamp)) {
// We can NEVER be in two locations at the same time! (also PR #886)
DEBUG_MSG("BUG!! positional timestamp unchanged from prev solution\n");
}
@@ -136,9 +137,9 @@ class GPSStatus : public Status
if (isDirty) {
if (hasLock) {
// In debug logs, identify position by @timestamp:stage (stage 3 = notify)
DEBUG_MSG("New GPS pos@%x:3 lat=%f, lon=%f, alt=%d, pdop=%.2f, track=%.2f, sats=%d\n", p.pos_timestamp,
DEBUG_MSG("New GPS pos@%x:3 lat=%f, lon=%f, alt=%d, pdop=%.2f, track=%.2f, speed=%.2f, sats=%d\n", p.timestamp,
p.latitude_i * 1e-7, p.longitude_i * 1e-7, p.altitude, p.PDOP * 1e-2, p.ground_track * 1e-5,
p.sats_in_view);
p.ground_speed * 1e-2, p.sats_in_view);
} else
DEBUG_MSG("No GPS lock\n");
onNewStatus.notifyObservers(this);
+1 -1
View File
@@ -15,7 +15,7 @@ bool scheduleOSCallback(PendableFunction callback, void *param1, uint32_t param2
return xTimerPendFunctionCall(callback, param1, param2, pdMS_TO_TICKS(delayMsec));
} */
#ifndef NO_ESP32
#ifdef ARCH_ESP32
// Super skanky quick hack to use hardware timers of the ESP32
static hw_timer_t *timer;
+289 -173
View File
@@ -5,13 +5,13 @@
#include "main.h"
#include "sleep.h"
#include "utils.h"
#include "buzz/buzz.h"
#ifdef TBEAM_V10
// FIXME. nasty hack cleanup how we load axp192
#undef AXP192_SLAVE_ADDRESS
#include "axp20x.h"
AXP20X_Class axp;
#ifdef HAS_PMU
#include "XPowersLibInterface.hpp"
#include "XPowersAXP2101.tpp"
#include "XPowersAXP192.tpp"
XPowersLibInterface *PMU = NULL;
#else
// Copy of the base class defined in axp20x.h.
// I'd rather not inlude axp20x.h as it brings Wire dependency.
@@ -21,20 +21,20 @@ class HasBatteryLevel
/**
* Battery state of charge, from 0 to 100 or -1 for unknown
*/
virtual int getBattPercentage() { return -1; }
virtual int getBatteryPercent() { return -1; }
/**
* The raw voltage of the battery or NAN if unknown
*/
virtual float getBattVoltage() { return NAN; }
virtual uint16_t getBattVoltage() { return 0; }
/**
* return true if there is a battery installed in this unit
*/
virtual bool isBatteryConnect() { return false; }
virtual bool isVBUSPlug() { return false; }
virtual bool isChargeing() { return false; }
virtual bool isVbusIn() { return false; }
virtual bool isCharging() { return false; }
};
#endif
@@ -45,7 +45,7 @@ Power *power;
using namespace meshtastic;
#ifndef AREF_VOLTAGE
#if defined(NRF52_SERIES)
#if defined(ARCH_NRF52)
/*
* Internal Reference is +/-0.6V, with an adjustable gain of 1/6, 1/5, 1/4,
* 1/3, 1/2 or 1, meaning 3.6, 3.0, 2.4, 1.8, 1.2 or 0.6V for the ADC levels.
@@ -76,14 +76,14 @@ class AnalogBatteryLevel : public HasBatteryLevel
*
* FIXME - use a lipo lookup table, the current % full is super wrong
*/
virtual int getBattPercentage() override
virtual int getBatteryPercent() override
{
float v = getBattVoltage();
if (v < noBatVolt)
return -1; // If voltage is super low assume no battery installed
#ifndef NRF52_SERIES
#ifdef ARCH_ESP32
// This does not work on a RAK4631 with battery connected
if (v > chargingVolt)
return 0; // While charging we can't report % full on the battery
@@ -95,7 +95,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
/**
* The raw voltage of the batteryin millivolts or NAN if unknown
*/
virtual float getBattVoltage() override
virtual uint16_t getBattVoltage() override
{
#ifndef ADC_MULTIPLIER
@@ -111,7 +111,18 @@ class AnalogBatteryLevel : public HasBatteryLevel
const uint32_t min_read_interval = 5000;
if (millis() - last_read_time_ms > min_read_interval) {
last_read_time_ms = millis();
#ifdef BATTERY_SENSE_SAMPLES
//Set the number of samples, it has an effect of increasing sensitivity, especially in complex electromagnetic environment.
uint32_t raw = 0;
for(uint32_t i=0; i<BATTERY_SENSE_SAMPLES;i++){
raw += analogRead(BATTERY_PIN);
}
raw = raw/BATTERY_SENSE_SAMPLES;
#else
uint32_t raw = analogRead(BATTERY_PIN);
#endif
float scaled;
#ifndef VBAT_RAW_TO_SCALED
scaled = 1000.0 * operativeAdcMultiplier * (AREF_VOLTAGE / 1024.0) * raw;
@@ -125,29 +136,42 @@ class AnalogBatteryLevel : public HasBatteryLevel
return last_read_value;
}
#else
return NAN;
return 0;
#endif
}
/**
* return true if there is a battery installed in this unit
*/
virtual bool isBatteryConnect() override { return getBattPercentage() != -1; }
virtual bool isBatteryConnect() override { return getBatteryPercent() != -1; }
/// If we see a battery voltage higher than physics allows - assume charger is pumping
/// in power
virtual bool isVBUSPlug() override { return getBattVoltage() > chargingVolt; }
virtual bool isVbusIn() override { return getBattVoltage() > chargingVolt; }
/// Assume charging if we have a battery and external power is connected.
/// we can't be smart enough to say 'full'?
virtual bool isChargeing() override { return isBatteryConnect() && isVBUSPlug(); }
virtual bool isCharging() override { return isBatteryConnect() && isVbusIn(); }
private:
/// If we see a battery voltage higher than physics allows - assume charger is pumping
/// in power
#ifndef BAT_FULLVOLT
#define BAT_FULLVOLT 4200
#endif
#ifndef BAT_EMPTYVOLT
#define BAT_EMPTYVOLT 3270
#endif
#ifndef BAT_CHARGINGVOLT
#define BAT_CHARGINGVOLT 4210
#endif
#ifndef BAT_NOBATVOLT
#define BAT_NOBATVOLT 2230
#endif
/// For heltecs with no battery connected, the measured voltage is 2204, so raising to 2230 from 2100
const float fullVolt = 4200, emptyVolt = 3270, chargingVolt = 4210, noBatVolt = 2230;
const float fullVolt = BAT_FULLVOLT, emptyVolt = BAT_EMPTYVOLT, chargingVolt = BAT_CHARGINGVOLT, noBatVolt = BAT_NOBATVOLT;
float last_read_value = 0.0;
uint32_t last_read_time_ms = 0;
};
@@ -168,11 +192,11 @@ bool Power::analogInit()
// disable any internal pullups
pinMode(BATTERY_PIN, INPUT);
#ifndef NO_ESP32
#ifdef ARCH_ESP32
// ESP32 needs special analog stuff
adcAttachPin(BATTERY_PIN);
#endif
#ifdef NRF52_SERIES
#ifdef ARCH_NRF52
#ifdef VBAT_AR_INTERNAL
analogReference(VBAT_AR_INTERNAL);
#else
@@ -196,7 +220,7 @@ bool Power::analogInit()
bool Power::setup()
{
bool found = axp192Init();
bool found = axpChipInit();
if (!found) {
found = analogInit();
@@ -209,10 +233,18 @@ bool Power::setup()
void Power::shutdown()
{
#ifdef TBEAM_V10
#ifdef HAS_PMU
DEBUG_MSG("Shutting down\n");
axp.shutdown();
#elif NRF52_SERIES
if(PMU){
PMU->setChargingLedMode(XPOWERS_CHG_LED_OFF);
PMU->shutdown();
}
#elif defined(ARCH_NRF52)
playBeep();
ledOff(PIN_LED1);
ledOff(PIN_LED2);
doDeepSleep(DELAY_FOREVER);
#endif
}
@@ -229,8 +261,8 @@ void Power::readPowerStatus()
if (hasBattery) {
batteryVoltageMv = batteryLevel->getBattVoltage();
// If the AXP192 returns a valid battery percentage, use it
if (batteryLevel->getBattPercentage() >= 0) {
batteryChargePercent = batteryLevel->getBattPercentage();
if (batteryLevel->getBatteryPercent() >= 0) {
batteryChargePercent = batteryLevel->getBatteryPercent();
} else {
// If the AXP192 returns a percentage less than 0, the feature is either not supported or there is an error
// In that case, we compute an estimate of the charge percent based on maximum and minimum voltages defined in
@@ -243,15 +275,15 @@ void Power::readPowerStatus()
// Notify any status instances that are observing us
const PowerStatus powerStatus2 =
PowerStatus(hasBattery ? OptTrue : OptFalse, batteryLevel->isVBUSPlug() ? OptTrue : OptFalse,
batteryLevel->isChargeing() ? OptTrue : OptFalse, batteryVoltageMv, batteryChargePercent);
PowerStatus(hasBattery ? OptTrue : OptFalse, batteryLevel->isVbusIn() ? OptTrue : OptFalse,
batteryLevel->isCharging() ? OptTrue : OptFalse, batteryVoltageMv, batteryChargePercent);
DEBUG_MSG("Battery: usbPower=%d, isCharging=%d, batMv=%d, batPct=%d\n", powerStatus2.getHasUSB(),
powerStatus2.getIsCharging(), powerStatus2.getBatteryVoltageMv(), powerStatus2.getBatteryChargePercent());
newStatus.notifyObservers(&powerStatus2);
// If we have a battery at all and it is less than 10% full, force deep sleep if we have more than 3 low readings in a row
// Supect fluctuating voltage on the RAK4631 to force it to deep sleep even if battery is at 85% after only a few days
#ifdef NRF52_SERIES
#ifdef ARCH_NRF52
if (powerStatus2.getHasBattery() && !powerStatus2.getHasUSB()) {
if (batteryLevel->getBattVoltage() < MIN_BAT_MILLIVOLTS) {
low_voltage_counter++;
@@ -277,41 +309,46 @@ int32_t Power::runOnce()
{
readPowerStatus();
#ifdef TBEAM_V10
#ifdef HAS_PMU
// WE no longer use the IRQ line to wake the CPU (due to false wakes from sleep), but we do poll
// the IRQ status by reading the registers over I2C
axp.readIRQ();
if(PMU){
if (axp.isVbusRemoveIRQ()) {
DEBUG_MSG("USB unplugged\n");
powerFSM.trigger(EVENT_POWER_DISCONNECTED);
}
if (axp.isVbusPlugInIRQ()) {
DEBUG_MSG("USB plugged In\n");
powerFSM.trigger(EVENT_POWER_CONNECTED);
}
/*
Other things we could check if we cared...
PMU->getIrqStatus();
if (axp.isChargingIRQ()) {
DEBUG_MSG("Battery start charging\n");
if(PMU->isVbusRemoveIrq()){
DEBUG_MSG("USB unplugged\n");
powerFSM.trigger(EVENT_POWER_DISCONNECTED);
}
if (PMU->isVbusInsertIrq()) {
DEBUG_MSG("USB plugged In\n");
powerFSM.trigger(EVENT_POWER_CONNECTED);
}
/*
Other things we could check if we cared...
if (PMU->isBatChagerStartIrq()) {
DEBUG_MSG("Battery start charging\n");
}
if (PMU->isBatChagerDoneIrq()) {
DEBUG_MSG("Battery fully charged\n");
}
if (PMU->isBatInsertIrq()) {
DEBUG_MSG("Battery inserted\n");
}
if (PMU->isBatRemoveIrq()) {
DEBUG_MSG("Battery removed\n");
}
if (PMU->isPekeyShortPressIrq()) {
DEBUG_MSG("PEK short button press\n");
}
*/
PMU->clearIrqStatus();
}
if (axp.isChargingDoneIRQ()) {
DEBUG_MSG("Battery fully charged\n");
}
if (axp.isBattPlugInIRQ()) {
DEBUG_MSG("Battery inserted\n");
}
if (axp.isBattRemoveIRQ()) {
DEBUG_MSG("Battery removed\n");
}
if (axp.isPEKShortPressIRQ()) {
DEBUG_MSG("PEK short button press\n");
}
*/
axp.clearIRQ();
#endif
// Only read once every 20 seconds once the power status for the app has been initialized
return (statusHandler && statusHandler->isInitialized()) ? (1000 * 20) : RUN_SAME;
}
@@ -324,128 +361,207 @@ int32_t Power::runOnce()
share the same i2c bus, instead use ssd1306 sleep mode DCDC2 -> unused DCDC3 0.7-3.5V @ 700mA max -> ESP32 (keep this on!) LDO1
30mA -> charges GPS backup battery // charges the tiny J13 battery by the GPS to power the GPS ram (for a couple of days), can
not be turned off LDO2 200mA -> LORA LDO3 200mA -> GPS
*
*/
bool Power::axp192Init()
bool Power::axpChipInit()
{
#ifdef TBEAM_V10
if (axp192_found) {
if (!axp.begin(Wire, AXP192_SLAVE_ADDRESS)) {
batteryLevel = &axp;
DEBUG_MSG("AXP192 Begin PASS\n");
#ifdef HAS_PMU
// axp.setChgLEDMode(LED_BLINK_4HZ);
DEBUG_MSG("DCDC1: %s\n", axp.isDCDC1Enable() ? "ENABLE" : "DISABLE");
DEBUG_MSG("DCDC2: %s\n", axp.isDCDC2Enable() ? "ENABLE" : "DISABLE");
DEBUG_MSG("LDO2: %s\n", axp.isLDO2Enable() ? "ENABLE" : "DISABLE");
DEBUG_MSG("LDO3: %s\n", axp.isLDO3Enable() ? "ENABLE" : "DISABLE");
DEBUG_MSG("DCDC3: %s\n", axp.isDCDC3Enable() ? "ENABLE" : "DISABLE");
DEBUG_MSG("Exten: %s\n", axp.isExtenEnable() ? "ENABLE" : "DISABLE");
DEBUG_MSG("----------------------------------------\n");
axp.setPowerOutPut(AXP192_LDO2, AXP202_ON); // LORA radio
// axp.setPowerOutPut(AXP192_LDO3, AXP202_ON); // GPS main power - now turned on in setGpsPower
axp.setPowerOutPut(AXP192_DCDC2, AXP202_ON);
axp.setPowerOutPut(AXP192_EXTEN, AXP202_ON);
axp.setPowerOutPut(AXP192_DCDC1, AXP202_ON);
axp.setDCDC1Voltage(3300); // for the OLED power
DEBUG_MSG("DCDC1: %s\n", axp.isDCDC1Enable() ? "ENABLE" : "DISABLE");
DEBUG_MSG("DCDC2: %s\n", axp.isDCDC2Enable() ? "ENABLE" : "DISABLE");
DEBUG_MSG("LDO2: %s\n", axp.isLDO2Enable() ? "ENABLE" : "DISABLE");
DEBUG_MSG("LDO3: %s\n", axp.isLDO3Enable() ? "ENABLE" : "DISABLE");
DEBUG_MSG("DCDC3: %s\n", axp.isDCDC3Enable() ? "ENABLE" : "DISABLE");
DEBUG_MSG("Exten: %s\n", axp.isExtenEnable() ? "ENABLE" : "DISABLE");
switch (config.power.charge_current) {
case Config_PowerConfig_ChargeCurrent_MAUnset:
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_450MA);
break;
case Config_PowerConfig_ChargeCurrent_MA100:
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_100MA);
break;
case Config_PowerConfig_ChargeCurrent_MA190:
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_190MA);
break;
case Config_PowerConfig_ChargeCurrent_MA280:
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_280MA);
break;
case Config_PowerConfig_ChargeCurrent_MA360:
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_360MA);
break;
case Config_PowerConfig_ChargeCurrent_MA450:
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_450MA);
break;
case Config_PowerConfig_ChargeCurrent_MA550:
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_550MA);
break;
case Config_PowerConfig_ChargeCurrent_MA630:
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_630MA);
break;
case Config_PowerConfig_ChargeCurrent_MA700:
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_700MA);
break;
case Config_PowerConfig_ChargeCurrent_MA780:
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_780MA);
break;
case Config_PowerConfig_ChargeCurrent_MA880:
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_880MA);
break;
case Config_PowerConfig_ChargeCurrent_MA960:
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_960MA);
break;
case Config_PowerConfig_ChargeCurrent_MA1000:
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_1000MA);
break;
case Config_PowerConfig_ChargeCurrent_MA1080:
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_1080MA);
break;
case Config_PowerConfig_ChargeCurrent_MA1160:
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_1160MA);
break;
case Config_PowerConfig_ChargeCurrent_MA1240:
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_1240MA);
break;
case Config_PowerConfig_ChargeCurrent_MA1320:
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_1320MA);
break;
}
#if 0
// Not connected
//val = 0xfc;
//axp._writeByte(AXP202_VHTF_CHGSET, 1, &val); // Set temperature protection
//not used
//val = 0x46;
//axp._writeByte(AXP202_OFF_CTL, 1, &val); // enable bat detection
#endif
axp.debugCharging();
#ifdef PMU_IRQ
pinMode(PMU_IRQ, INPUT);
attachInterrupt(
PMU_IRQ, [] { pmu_irq = true; }, FALLING);
axp.adc1Enable(AXP202_BATT_CUR_ADC1, 1);
// we do not look for AXP202_CHARGING_FINISHED_IRQ & AXP202_CHARGING_IRQ because it occurs repeatedly while there is
// no battery also it could cause inadvertent waking from light sleep just because the battery filled
// we don't look for AXP202_BATT_REMOVED_IRQ because it occurs repeatedly while no battery installed
// we don't look at AXP202_VBUS_REMOVED_IRQ because we don't have anything hooked to vbus
axp.enableIRQ(AXP202_BATT_CONNECT_IRQ | AXP202_VBUS_CONNECT_IRQ | AXP202_PEK_SHORTPRESS_IRQ, 1);
axp.clearIRQ();
#endif
readPowerStatus();
if (!PMU) {
PMU = new XPowersAXP2101(Wire, I2C_SDA, I2C_SCL);
if (!PMU->init()) {
DEBUG_MSG("Warning: Failed to find AXP2101 power management\n");
delete PMU;
PMU = NULL;
} else {
DEBUG_MSG("AXP192 Begin FAIL\n");
DEBUG_MSG("AXP2101 PMU init succeeded, using AXP2101 PMU\n");
}
} else {
DEBUG_MSG("AXP192 not found\n");
}
return axp192_found;
if (!PMU) {
PMU = new XPowersAXP192(Wire, I2C_SDA, I2C_SCL);
if (!PMU->init()) {
DEBUG_MSG("Warning: Failed to find AXP192 power management\n");
delete PMU;
PMU = NULL;
} else {
DEBUG_MSG("AXP192 PMU init succeeded, using AXP192 PMU\n");
}
}
if (!PMU) {
/*
* In XPowersLib, if the XPowersAXPxxx object is released, Wire.end() will be called at the same time.
* In order not to affect other devices, if the initialization of the PMU fails, Wire needs to be re-initialized once,
* if there are multiple devices sharing the bus.
* * */
Wire.begin(I2C_SDA, I2C_SCL);
return false;
}
batteryLevel = PMU;
if (PMU->getChipModel() == XPOWERS_AXP192) {
// lora radio power channel
PMU->setPowerChannelVoltage(XPOWERS_LDO2, 3300);
PMU->enablePowerOutput(XPOWERS_LDO2);
// oled module power channel,
// disable it will cause abnormal communication between boot and AXP power supply,
// do not turn it off
PMU->setPowerChannelVoltage(XPOWERS_DCDC1, 3300);
// enable oled power
PMU->enablePowerOutput(XPOWERS_DCDC1);
// gnss module power channel - now turned on in setGpsPower
PMU->setPowerChannelVoltage(XPOWERS_LDO3, 3300);
// PMU->enablePowerOutput(XPOWERS_LDO3);
//protected oled power source
PMU->setProtectedChannel(XPOWERS_DCDC1);
//protected esp32 power source
PMU->setProtectedChannel(XPOWERS_DCDC3);
//disable not use channel
PMU->disablePowerOutput(XPOWERS_DCDC2);
//disable all axp chip interrupt
PMU->disableIRQ(XPOWERS_AXP192_ALL_IRQ);
// Set constant current charging current
PMU->setChargerConstantCurr(XPOWERS_AXP192_CHG_CUR_450MA);
} else if (PMU->getChipModel() == XPOWERS_AXP2101) {
// 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
*/
PMU->setPowerChannelVoltage(XPOWERS_ALDO4, 3300);
PMU->enablePowerOutput(XPOWERS_ALDO4);
// lora radio power channel
PMU->setPowerChannelVoltage(XPOWERS_ALDO3, 3300);
PMU->enablePowerOutput(XPOWERS_ALDO3);
// m.2 interface
PMU->setPowerChannelVoltage(XPOWERS_DCDC3, 3300);
PMU->enablePowerOutput(XPOWERS_DCDC3);
// PMU->setPowerChannelVoltage(XPOWERS_DCDC4, 3300);
// PMU->enablePowerOutput(XPOWERS_DCDC4);
//not use channel
PMU->disablePowerOutput(XPOWERS_DCDC2); //not elicited
PMU->disablePowerOutput(XPOWERS_DCDC5); //not elicited
PMU->disablePowerOutput(XPOWERS_DLDO1); //Invalid power channel, it does not exist
PMU->disablePowerOutput(XPOWERS_DLDO2); //Invalid power channel, it does not exist
PMU->disablePowerOutput(XPOWERS_VBACKUP);
//disable all axp chip interrupt
PMU->disableIRQ(XPOWERS_AXP2101_ALL_IRQ);
//Set the constant current charging current of AXP2101, temporarily use 500mA by default
PMU->setChargerConstantCurr(XPOWERS_AXP2101_CHG_CUR_500MA);
}
PMU->clearIrqStatus();
// TBeam1.1 /T-Beam S3-Core has no external TS detection,
// it needs to be disabled, otherwise it will cause abnormal charging
PMU->disableTSPinMeasure();
// PMU->enableSystemVoltageMeasure();
PMU->enableVbusVoltageMeasure();
PMU->enableBattVoltageMeasure();
DEBUG_MSG("=======================================================================\n");
if (PMU->isChannelAvailable(XPOWERS_DCDC1)) {
DEBUG_MSG("DC1 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC1) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC1));
}
if (PMU->isChannelAvailable(XPOWERS_DCDC2)) {
DEBUG_MSG("DC2 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC2));
}
if (PMU->isChannelAvailable(XPOWERS_DCDC3)) {
DEBUG_MSG("DC3 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC3) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC3));
}
if (PMU->isChannelAvailable(XPOWERS_DCDC4)) {
DEBUG_MSG("DC4 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC4) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC4));
}
if (PMU->isChannelAvailable(XPOWERS_LDO2)) {
DEBUG_MSG("LDO2 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_LDO2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_LDO2));
}
if (PMU->isChannelAvailable(XPOWERS_LDO3)) {
DEBUG_MSG("LDO3 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_LDO3) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_LDO3));
}
if (PMU->isChannelAvailable(XPOWERS_ALDO1)) {
DEBUG_MSG("ALDO1: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO1) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO1));
}
if (PMU->isChannelAvailable(XPOWERS_ALDO2)) {
DEBUG_MSG("ALDO2: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO2));
}
if (PMU->isChannelAvailable(XPOWERS_ALDO3)) {
DEBUG_MSG("ALDO3: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO3) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO3));
}
if (PMU->isChannelAvailable(XPOWERS_ALDO4)) {
DEBUG_MSG("ALDO4: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO4) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO4));
}
if (PMU->isChannelAvailable(XPOWERS_BLDO1)) {
DEBUG_MSG("BLDO1: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_BLDO1) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_BLDO1));
}
if (PMU->isChannelAvailable(XPOWERS_BLDO2)) {
DEBUG_MSG("BLDO2: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_BLDO2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_BLDO2));
}
DEBUG_MSG("=======================================================================\n");
//Set up the charging voltage, AXP2101/AXP192 4.2V gear is the same
// XPOWERS_AXP192_CHG_VOL_4V2 = XPOWERS_AXP2101_CHG_VOL_4V2
PMU->setChargeTargetVoltage(XPOWERS_AXP192_CHG_VOL_4V2);
// Set PMU shutdown voltage at 2.6V to maximize battery utilization
PMU->setSysPowerDownVoltage(2600);
#ifdef PMU_IRQ
uint64_t pmuIrqMask = 0;
if (PMU->getChipModel() == XPOWERS_AXP192) {
pmuIrqMask = XPOWERS_AXP192_VBUS_INSERT_IRQ | XPOWERS_AXP192_BAT_INSERT_IRQ | XPOWERS_AXP192_PKEY_SHORT_IRQ;
} else if (PMU->getChipModel() == XPOWERS_AXP2101) {
pmuIrqMask = XPOWERS_AXP2101_VBUS_INSERT_IRQ | XPOWERS_AXP2101_BAT_INSERT_IRQ | XPOWERS_AXP2101_PKEY_SHORT_IRQ;
}
pinMode(PMU_IRQ, INPUT);
attachInterrupt(
PMU_IRQ, [] { pmu_irq = true; }, FALLING);
// we do not look for AXPXXX_CHARGING_FINISHED_IRQ & AXPXXX_CHARGING_IRQ because it occurs repeatedly while there is
// no battery also it could cause inadvertent waking from light sleep just because the battery filled
// we don't look for AXPXXX_BATT_REMOVED_IRQ because it occurs repeatedly while no battery installed
// we don't look at AXPXXX_VBUS_REMOVED_IRQ because we don't have anything hooked to vbus
PMU->enableIRQ(pmuIrqMask);
PMU->clearIrqStatus();
#endif /*PMU_IRQ*/
readPowerStatus();
pmu_found = true;
return pmu_found;
#else
return false;
#endif
+23 -49
View File
@@ -11,30 +11,30 @@
/// Should we behave as if we have AC power now?
static bool isPowered()
{
// Completely circumvents the battery / power sensing logic and assumes constant power source
if (config.power.is_always_powered) {
// Circumvent the battery sensing logic and assumes constant power if no battery pin or power mgmt IC
#if !defined(BATTERY_PIN) && !defined(HAS_AXP192) && !defined(HAS_AXP2101)
return true;
}
#endif
bool isRouter = (config.device.role == Config_DeviceConfig_Role_Router ? 1 : 0);
bool isRouter = (config.device.role == Config_DeviceConfig_Role_ROUTER ? 1 : 0);
// If we are not a router and we already have AC power go to POWER state after init, otherwise go to ON
// We assume routers might be powered all the time, but from a low current (solar) source
bool isLowPower = config.power.is_low_power || isRouter;
bool isPowerSavingMode = config.power.is_power_saving || isRouter;
/* To determine if we're externally powered, assumptions
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.
*/
return !isLowPower && powerStatus && (!powerStatus->getHasBattery() || powerStatus->getHasUSB());
return !isPowerSavingMode && powerStatus && (!powerStatus->getHasBattery() || powerStatus->getHasUSB());
}
static void sdsEnter()
{
DEBUG_MSG("Enter state: SDS\n");
// FIXME - make sure GPS and LORA radio are off first - because we want close to zero current draw
doDeepSleep(config.power.sds_secs ? config.power.sds_secs : default_sds_secs * 1000LL);
doDeepSleep(config.power.sds_secs * 1000);
}
extern Power *power;
@@ -51,8 +51,7 @@ static uint32_t secsSlept;
static void lsEnter()
{
DEBUG_MSG("lsEnter begin, ls_secs=%u\n",
config.power.ls_secs ? config.power.ls_secs : default_ls_secs);
DEBUG_MSG("lsEnter begin, ls_secs=%u\n", config.power.ls_secs);
screen->setOn(false);
secsSlept = 0; // How long have we been sleeping this time
@@ -63,10 +62,10 @@ static void lsIdle()
{
// DEBUG_MSG("lsIdle begin ls_secs=%u\n", getPref_ls_secs());
#ifndef NO_ESP32
#ifdef ARCH_ESP32
// Do we have more sleeping to do?
if (secsSlept < config.power.ls_secs ? config.power.ls_secs : default_ls_secs * 1000) {
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;
@@ -200,8 +199,7 @@ static void onEnter()
uint32_t now = millis();
if (now - lastPingMs >
30 * 1000) { // if more than a minute since our last press, ask node we are looking at to update their state
if ((now - lastPingMs) > 30 * 1000) { // if more than a minute since our last press, ask node we are looking at to update their state
if (displayedNodeNum)
service.sendNetworkPing(displayedNodeNum, true); // Refresh the currently displayed node
lastPingMs = now;
@@ -239,10 +237,10 @@ Fsm powerFSM(&stateBOOT);
void PowerFSM_setup()
{
bool isRouter = (config.device.role == Config_DeviceConfig_Role_Router ? 1 : 0);
bool isRouter = (config.device.role == Config_DeviceConfig_Role_ROUTER ? 1 : 0);
bool hasPower = isPowered();
DEBUG_MSG("PowerFSM init, USB power=%d\n", hasPower);
DEBUG_MSG("PowerFSM init, USB power=%d\n", hasPower ? 1 : 0);
powerFSM.add_timed_transition(&stateBOOT, hasPower ? &statePOWER : &stateON, 3 * 1000, NULL, "boot timeout");
// wake timer expired or a packet arrived
@@ -251,8 +249,7 @@ void PowerFSM_setup()
// We need this transition, because we might not transition if we were waiting to enter light-sleep, because when we wake from
// light sleep we _always_ transition to NB or dark and
powerFSM.add_transition(&stateLS, isRouter ? &stateNB : &stateDARK, EVENT_PACKET_FOR_PHONE, NULL,
"Received packet, exiting light sleep");
powerFSM.add_transition(&stateLS, isRouter ? &stateNB : &stateDARK, EVENT_PACKET_FOR_PHONE, NULL, "Received packet, exiting light sleep");
powerFSM.add_transition(&stateNB, &stateNB, EVENT_PACKET_FOR_PHONE, NULL, "Received packet, resetting win wake");
// Handle press events - note: we ignore button presses when in API mode
@@ -261,8 +258,7 @@ void PowerFSM_setup()
powerFSM.add_transition(&stateDARK, &stateON, EVENT_PRESS, NULL, "Press");
powerFSM.add_transition(&statePOWER, &statePOWER, EVENT_PRESS, screenPress, "Press");
powerFSM.add_transition(&stateON, &stateON, EVENT_PRESS, screenPress, "Press"); // reenter On to restart our timers
powerFSM.add_transition(&stateSERIAL, &stateSERIAL, EVENT_PRESS, screenPress,
"Press"); // Allow button to work while in serial API
powerFSM.add_transition(&stateSERIAL, &stateSERIAL, EVENT_PRESS, screenPress, "Press"); // Allow button to work while in serial API
// Handle critically low power battery by forcing deep sleep
powerFSM.add_transition(&stateBOOT, &stateSDS, EVENT_LOW_BATTERY, NULL, "LowBat");
@@ -333,48 +329,26 @@ void PowerFSM_setup()
powerFSM.add_transition(&stateDARK, &stateON, EVENT_FIRMWARE_UPDATE, NULL, "Got firmware update");
powerFSM.add_transition(&stateON, &stateON, EVENT_FIRMWARE_UPDATE, NULL, "Got firmware update");
powerFSM.add_timed_transition(&stateON, &stateDARK,
config.display.screen_on_secs ? config.display.screen_on_secs
: 60 * 1000,
NULL, "Screen-on timeout");
powerFSM.add_timed_transition(&stateON, &stateDARK, getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs), NULL, "Screen-on timeout");
// On most boards we use light-sleep to be our main state, but on NRF52 we just stay in DARK
State *lowPowerState = &stateLS;
uint32_t meshSds = 0;
#ifndef NRF52_SERIES
#ifdef ARCH_ESP32
// We never enter light-sleep or NB states on NRF52 (because the CPU uses so little power normally)
// See: https://github.com/meshtastic/Meshtastic-device/issues/1071
if (isRouter || config.power.is_power_saving) {
powerFSM.add_timed_transition(&stateNB, &stateLS, getConfiguredOrDefaultMs(config.power.min_wake_secs, default_min_wake_secs), NULL, "Min wake timeout");
powerFSM.add_timed_transition(&stateDARK, &stateLS, getConfiguredOrDefaultMs(config.power.wait_bluetooth_secs, default_wait_bluetooth_secs), NULL, "Bluetooth timeout");
}
// I don't think this transition is correct, turning off for now - @geeksville
// powerFSM.add_timed_transition(&stateDARK, &stateNB, getPref_phone_timeout_secs() * 1000, NULL, "Phone timeout");
powerFSM.add_timed_transition(&stateNB, &stateLS,
config.power.min_wake_secs ? config.power.min_wake_secs
: default_min_wake_secs * 1000,
NULL, "Min wake timeout");
powerFSM.add_timed_transition(&stateDARK, &stateLS,
config.power.wait_bluetooth_secs
? config.power.wait_bluetooth_secs
: default_wait_bluetooth_secs * 1000,
NULL, "Bluetooth timeout");
meshSds = config.power.mesh_sds_timeout_secs ? config.power.mesh_sds_timeout_secs
: default_mesh_sds_timeout_secs;
} else {
meshSds = UINT32_MAX;
}
#else
#elif defined (ARCH_NRF52)
lowPowerState = &stateDARK;
meshSds = UINT32_MAX; // Workaround for now: Don't go into deep sleep on the RAK4631
#endif
if (meshSds != UINT32_MAX)
powerFSM.add_timed_transition(lowPowerState, &stateSDS, meshSds * 1000, NULL, "mesh timeout");
if (config.power.sds_secs != UINT32_MAX)
powerFSM.add_timed_transition(lowPowerState, &stateSDS, config.power.sds_secs * 1000, NULL, "mesh timeout");
powerFSM.run_machine(); // run one interation of the state machine, so we run our on enter tasks for the initial DARK state
}
+8 -12
View File
@@ -1,6 +1,7 @@
#include "configuration.h"
#include "RedirectablePrint.h"
#include "RTC.h"
#include "NodeDB.h"
#include "concurrency/OSThread.h"
// #include "wifi/WiFiServerAPI.h"
#include <assert.h>
@@ -30,7 +31,9 @@ size_t RedirectablePrint::write(uint8_t c)
// optionally send chars to TCP also
//WiFiServerPort::debugOut(c);
dest->write(c);
if (!config.has_lora || config.device.serial_enabled)
dest->write(c);
return 1; // We always claim one was written, rather than trusting what the
// serial port said (which could be zero)
}
@@ -38,20 +41,13 @@ size_t RedirectablePrint::write(uint8_t c)
size_t RedirectablePrint::vprintf(const char *format, va_list arg)
{
va_list copy;
static char printBuf[160];
va_copy(copy, arg);
int len = vsnprintf(printBuf, printBufLen, format, copy);
int len = vsnprintf(printBuf, sizeof(printBuf), format, copy);
va_end(copy);
if (len < 0) {
va_end(arg);
return 0;
};
if (len >= (int)printBufLen) {
delete[] printBuf;
printBufLen *= 2;
printBuf = new char[printBufLen];
len = vsnprintf(printBuf, printBufLen, format, arg);
}
if (len < 0) return 0;
len = Print::write(printBuf, len);
return len;
-4
View File
@@ -12,10 +12,6 @@ class RedirectablePrint : public Print
{
Print *dest;
/// We dynamically grow this scratch buffer if necessary
char *printBuf = new char[64];
size_t printBufLen = 64;
/// Used to allow multiple logDebug messages to appear on a single log line
bool isContinuationMessage = false;
+19 -10
View File
@@ -4,6 +4,8 @@
#include "configuration.h"
#define Port Serial
// Defaulting to the formerly removed phone_timeout_secs value of 15 minutes
#define SERIAL_CONNECTION_TIMEOUT (15 * 60) * 1000UL
SerialConsole *console;
@@ -18,6 +20,9 @@ void consolePrintf(const char *format, ...)
va_start(arg, format);
console->vprintf(format, arg);
va_end(arg);
#ifdef ARCH_ESP32
console->flush();
#endif
}
SerialConsole::SerialConsole() : StreamAPI(&Port), RedirectablePrint(&Port)
@@ -28,7 +33,7 @@ SerialConsole::SerialConsole() : StreamAPI(&Port), RedirectablePrint(&Port)
// setDestination(&noopPrint); for testing, try turning off 'all' debug output and see what leaks
Port.begin(SERIAL_BAUD);
#ifdef NRF52_SERIES
#ifdef ARCH_NRF52
time_t timeout = millis();
while (!Port) {
if ((millis() - timeout) < 5000) {
@@ -41,13 +46,12 @@ SerialConsole::SerialConsole() : StreamAPI(&Port), RedirectablePrint(&Port)
emitRebooted();
}
// For the serial port we can't really detect if any client is on the other side, so instead just look for recent messages
bool SerialConsole::checkIsConnected()
{
uint32_t now = millis();
return (now - lastContactMsec) < config.power.phone_timeout_secs
? config.power.phone_timeout_secs
: default_phone_timeout_secs * 1000UL;
return (now - lastContactMsec) < SERIAL_CONNECTION_TIMEOUT;
}
/**
@@ -56,10 +60,15 @@ bool SerialConsole::checkIsConnected()
*/
bool SerialConsole::handleToRadio(const uint8_t *buf, size_t len)
{
// Turn off debug serial printing once the API is activated, because other threads could print and corrupt packets
if (!config.device.debug_log_enabled)
setDestination(&noopPrint);
canWrite = true;
// only talk to the API once the configuration has been loaded and we're sure the serial port is not disabled.
if (config.has_lora && config.device.serial_enabled) {
// Turn off debug serial printing once the API is activated, because other threads could print and corrupt packets
if (!config.device.debug_log_enabled)
setDestination(&noopPrint);
canWrite = true;
return StreamAPI::handleToRadio(buf, len);
}
return StreamAPI::handleToRadio(buf, len);
}else{
return false;
}
}
+1
View File
@@ -14,4 +14,5 @@ enum class Cmd {
STOP_BOOT_SCREEN,
PRINT,
START_SHUTDOWN_SCREEN,
START_REBOOT_SCREEN,
};
+54 -181
View File
@@ -25,6 +25,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#pragma once
#include <Arduino.h>
#ifdef RV3028_RTC
#include "Melopero_RV3028.h"
#endif
@@ -61,79 +62,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/// Convert a preprocessor name into a quoted string and if that string is empty use "unset"
#define optstr(s) (xstr(s)[0] ? xstr(s) : "unset")
#ifdef PORTDUINO
#define NO_ESP32 // Don't use ESP32 libs (mainly bluetooth)
#elif defined(NRF52_SERIES) // All of the NRF52 targets are configured using variant.h, so this section shouldn't need to be
// board specific
//
// Standard definitions for NRF52 targets
//
#define NO_ESP32 // Don't use ESP32 libs (mainly bluetooth)
// We bind to the GPS using variant.h instead for this platform (Serial1)
#define LED_PIN PIN_LED1 // LED1 on nrf52840-DK
// If the variant filed defines as standard button
#ifdef PIN_BUTTON1
#define BUTTON_PIN PIN_BUTTON1
// Nop definition for these attributes that are specific to ESP32
#ifndef EXT_RAM_ATTR
#define EXT_RAM_ATTR
#endif
#ifdef PIN_BUTTON2
#define BUTTON_PIN_ALT PIN_BUTTON2
#ifndef IRAM_ATTR
#define IRAM_ATTR
#endif
#ifdef PIN_BUTTON_TOUCH
#define BUTTON_PIN_TOUCH PIN_BUTTON_TOUCH
#endif
#else
//
// Standard definitions for ESP32 targets
//
#define HAS_WIFI
#define GPS_SERIAL_NUM 1
#define GPS_RX_PIN 34
#ifdef USE_JTAG
#define GPS_TX_PIN -1
#else
#define GPS_TX_PIN 12
#endif
// -----------------------------------------------------------------------------
// LoRa SPI
// -----------------------------------------------------------------------------
// NRF52 boards will define this in variant.h
#ifndef RF95_SCK
#define RF95_SCK 5
#define RF95_MISO 19
#define RF95_MOSI 27
#define RF95_NSS 18
#endif
#endif
#ifndef TTGO_T_ECHO
#define GPS_UBLOX
#endif
//
// Standard definitions for !ESP32 targets
//
#ifdef NO_ESP32
// Nop definition for these attributes - not used on NRF52
#define EXT_RAM_ATTR
#define IRAM_ATTR
#define RTC_DATA_ATTR
#ifndef RTC_DATA_ATTR
#define RTC_DATA_ATTR
#endif
// -----------------------------------------------------------------------------
@@ -141,7 +78,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// -----------------------------------------------------------------------------
// Disable use of the NTP library and related features
//#define DISABLE_NTP
// #define DISABLE_NTP
// Disable the welcome screen and allow
//#define DISABLE_WELCOME_UNSET
@@ -157,18 +94,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// Define this if you know you have that controller or your "SSD1306" misbehaves.
//#define USE_SH1106
// Flip the screen upside down by default as it makes more sense on T-BEAM
// devices. Comment this out to not rotate screen 180 degrees.
#define SCREEN_FLIP_VERTICALLY
// Define if screen should be mirrored left to right
// #define SCREEN_MIRROR
// The m5stack I2C Keyboard (also RAK14004)
#define CARDKB_ADDR 0x5F
// The older M5 Faces I2C Keyboard
#define FACESKB_ADDR 0x88
// -----------------------------------------------------------------------------
// SENSOR
// -----------------------------------------------------------------------------
#define BME_ADDR 0x76
#define BME_ADDR_ALTERNATE 0x77
#define MCP9808_ADDR 0x18
#define INA_ADDR 0x40
#define INA_ADDR_ALTERNATE 0x41
// -----------------------------------------------------------------------------
// GPS
@@ -180,109 +119,43 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define GPS_THREAD_INTERVAL 100
#endif
#if defined(TBEAM_V10)
// This string must exactly match the case used in release file names or the android updater won't work
#define HW_VENDOR HardwareModel_TBEAM
#elif defined(TBEAM_V07)
// This string must exactly match the case used in release file names or the android updater won't work
#define HW_VENDOR HardwareModel_TBEAM0p7
#elif defined(DIY_V1)
// This string must exactly match the case used in release file names or the android updater won't work
#define HW_VENDOR HardwareModel_DIY_V1
#elif defined(RAK_11200)
// This string must exactly match the case used in release file names or the android updater won't work
#define HW_VENDOR HardwareModel_RAK11200
#elif defined(ARDUINO_HELTEC_WIFI_LORA_32_V2)
#ifdef HELTEC_V2_0
// This string must exactly match the case used in release file names or the android updater won't work
#define HW_VENDOR HardwareModel_HELTEC_V2_0
#endif
#ifdef HELTEC_V2_1
// This string must exactly match the case used in release file names or the android updater won't work
#define HW_VENDOR HardwareModel_HELTEC_V2_1
#endif
#elif defined(ARDUINO_HELTEC_WIFI_LORA_32)
#define HW_VENDOR HardwareModel_HELTEC_V1
#elif defined(TLORA_V1)
#define HW_VENDOR HardwareModel_TLORA_V1
#elif defined(TLORA_V2)
// This string must exactly match the case used in release file names or the android updater won't work
#define HW_VENDOR HardwareModel_TLORA_V2
#elif defined(TLORA_V1_3)
// This string must exactly match the case used in release file names or the android updater won't work
#define HW_VENDOR HardwareModel_TLORA_V1_1p3
#elif defined(TLORA_V2_1_16)
// This string must exactly match the case used in release file names or the android updater won't work
#define HW_VENDOR HardwareModel_TLORA_V2_1_1p6
#elif defined(GENIEBLOCKS)
// This string must exactly match the case used in release file names or the android updater won't work
#define HW_VENDOR HardwareModel_GENIEBLOCKS
#elif defined(PRIVATE_HW)
// This string must exactly match the case used in release file names or the android updater won't work
#define HW_VENDOR HardwareModel_PRIVATE_HW
#endif
#ifdef ARDUINO_NRF52840_PCA10056
// This string must exactly match the case used in release file names or the android updater won't work
#define HW_VENDOR HardwareModel_NRF52840DK
// This board uses 0 to be mean LED on
#undef LED_INVERTED
#define LED_INVERTED 1
#elif defined(ARDUINO_NRF52840_PPR)
#define HW_VENDOR HardwareModel_PPR
#elif defined(RAK4630)
#define HW_VENDOR HardwareModel_RAK4631
#elif defined(TTGO_T_ECHO)
#define HW_VENDOR HardwareModel_T_ECHO
#elif defined(NANO_G1)
#define HW_VENDOR HardwareModel_NANO_G1
#elif defined(NORDIC_PCA10059)
#define HW_VENDOR HardwareModel_NRF52840_PCA10059
#elif defined(M5STACK)
#define HW_VENDOR HardwareModel_M5STACK
#elif NRF52_SERIES
#define HW_VENDOR HardwareModel_NRF52_UNKNOWN
#elif PORTDUINO
#define HW_VENDOR HardwareModel_PORTDUINO
#endif
/* Step #1: offer chance for variant-specific defines */
#include "variant.h"
/* Step #2: follow with defines common to the architecture;
also enable HAS_ option not specifically disabled by variant.h */
#include "architecture.h"
/* Step #3: mop up with disabled values for HAS_ options not handled by the above two */
#ifndef HAS_WIFI
#define HAS_WIFI 0
#endif
#ifndef HAS_SCREEN
#define HAS_SCREEN 0
#endif
#ifndef HAS_WIRE
#define HAS_WIRE 0
#endif
#ifndef HAS_GPS
#define HAS_GPS 0
#endif
#ifndef HAS_BUTTON
#define HAS_BUTTON 0
#endif
#ifndef HAS_TELEMETRY
#define HAS_TELEMETRY 0
#endif
#ifndef HAS_RADIO
#define HAS_RADIO 0
#endif
#ifndef HAS_RTC
#define HAS_RTC 0
#endif
#include "RF95Configuration.h"
#include "DebugConfiguration.h"
#ifndef HW_VENDOR
#error HW_VENDOR must be defined
#endif
-1
View File
@@ -1 +0,0 @@
// Placeholder FIXME
+61 -20
View File
@@ -1,8 +1,32 @@
#include "../configuration.h"
#include "../main.h"
#include <Wire.h>
#include "mesh/generated/telemetry.pb.h"
// AXP192 and AXP2101 have the same device address, we just need to identify it in Power.cpp
#ifndef XPOWERS_AXP192_AXP2101_ADDRESS
#define XPOWERS_AXP192_AXP2101_ADDRESS 0x34
#endif
#if HAS_WIRE
uint16_t getRegisterValue(uint8_t address, uint8_t reg, uint8_t length) {
uint16_t value = 0x00;
Wire.beginTransmission(address);
Wire.write(reg);
Wire.endTransmission();
delay(20);
Wire.requestFrom(address, length);
DEBUG_MSG("Wire.available() = %d\n", Wire.available());
if (Wire.available() == 2) {
// Read MSB, then LSB
value = (uint16_t)Wire.read() << 8;
value |= Wire.read();
} else if (Wire.available()) {
value = Wire.read();
}
return value;
}
#ifndef NO_WIRE
uint8_t oled_probe(byte addr)
{
uint8_t r = 0;
@@ -22,7 +46,7 @@ uint8_t oled_probe(byte addr)
if (r == 0x08 || r == 0x00) {
o_probe = 2; // SH1106
} else if ( r == 0x03 || r == 0x06 || r == 0x07) {
} else if ( r == 0x03 || r == 0x04 || r == 0x06 || r == 0x07) {
o_probe = 1; // SSD1306
}
c++;
@@ -34,7 +58,7 @@ uint8_t oled_probe(byte addr)
void scanI2Cdevice(void)
{
byte err, addr;
uint8_t r = 0x00;
uint16_t registerValue = 0x00;
int nDevices = 0;
for (addr = 1; addr < 127; addr++) {
Wire.beginTransmission(addr);
@@ -74,15 +98,8 @@ void scanI2Cdevice(void)
if (addr == CARDKB_ADDR) {
cardkb_found = addr;
// Do we have the RAK14006 instead?
Wire.beginTransmission(addr);
Wire.write(0x04); // SENSOR_GET_VERSION
Wire.endTransmission();
delay(20);
Wire.requestFrom((int)addr, 1);
if (Wire.available()) {
r = Wire.read();
}
if (r == 0x02) { // KEYPAD_VERSION
registerValue = getRegisterValue(addr, 0x04, 1);
if (registerValue == 0x02) { // KEYPAD_VERSION
DEBUG_MSG("RAK14004 found\n");
kb_model = 0x02;
} else {
@@ -90,20 +107,44 @@ void scanI2Cdevice(void)
kb_model = 0x00;
}
}
if (addr == FACESKB_ADDR) {
faceskb_found = addr;
DEBUG_MSG("m5 Faces found\n");
}
if (addr == ST7567_ADDRESS) {
screen_found = addr;
DEBUG_MSG("st7567 display found\n");
}
#ifdef AXP192_SLAVE_ADDRESS
if (addr == AXP192_SLAVE_ADDRESS) {
axp192_found = true;
DEBUG_MSG("axp192 PMU found\n");
#ifdef HAS_PMU
if (addr == XPOWERS_AXP192_AXP2101_ADDRESS) {
pmu_found = true;
DEBUG_MSG("axp192/axp2101 PMU found\n");
}
#endif
if (addr == BME_ADDR || addr == BME_ADDR_ALTERNATE) {
registerValue = getRegisterValue(addr, 0xD0, 1); // GET_ID
if (registerValue == 0x61) {
DEBUG_MSG("BME-680 sensor found at address 0x%x\n", (uint8_t)addr);
nodeTelemetrySensorsMap[TelemetrySensorType_BME680] = addr;
} else if (registerValue == 0x60) {
DEBUG_MSG("BME-280 sensor found at address 0x%x\n", (uint8_t)addr);
nodeTelemetrySensorsMap[TelemetrySensorType_BME280] = addr;
} else {
DEBUG_MSG("BMP-280 sensor found at address 0x%x\n", (uint8_t)addr);
nodeTelemetrySensorsMap[TelemetrySensorType_BMP280] = addr;
}
}
if (addr == INA_ADDR || addr == INA_ADDR_ALTERNATE) {
registerValue = getRegisterValue(addr, 0xFE, 2);
DEBUG_MSG("Register MFG_UID: 0x%x\n", registerValue);
if (registerValue == 0x5449) {
DEBUG_MSG("INA260 sensor found at address 0x%x\n", (uint8_t)addr);
nodeTelemetrySensorsMap[TelemetrySensorType_INA260] = addr;
} else { // Assume INA219 if INA260 ID is not found
DEBUG_MSG("INA219 sensor found at address 0x%x\n", (uint8_t)addr);
nodeTelemetrySensorsMap[TelemetrySensorType_INA219] = addr;
}
}
if (addr == MCP9808_ADDR) {
nodeTelemetrySensorsMap[TelemetrySensorType_MCP9808] = addr;
DEBUG_MSG("MCP9808 sensor found at address 0x%x\n", (uint8_t)addr);
}
} else if (err == 4) {
DEBUG_MSG("Unknow error at address 0x%x\n", addr);
}
+1 -1
View File
@@ -8,4 +8,4 @@
#define RECORD_CRITICALERROR(code) recordCriticalError(code, __LINE__, __FILE__)
/// Record an error that should be reported via analytics
void recordCriticalError(CriticalErrorCode code = CriticalErrorCode_Unspecified, uint32_t address = 0, const char *filename = NULL);
void recordCriticalError(CriticalErrorCode code = CriticalErrorCode_UNSPECIFIED, uint32_t address = 0, const char *filename = NULL);
-160
View File
@@ -1,160 +0,0 @@
#ifndef USE_NEW_ESP32_BLUETOOTH
#include <Arduino.h>
#include "../concurrency/LockGuard.h"
#include "../graphics/Screen.h"
#include "../main.h"
#include "BluetoothSoftwareUpdate.h"
#include "NodeDB.h"
#include "PowerFSM.h"
#include "RadioLibInterface.h"
#include "configuration.h"
#include "nimble/BluetoothUtil.h"
#include <CRC32.h>
#include <Update.h>
int16_t updateResultHandle = -1;
static CRC32 crc;
static uint32_t updateExpectedSize, updateActualSize;
static uint8_t update_result;
static uint8_t update_region;
static concurrency::Lock *updateLock;
/// Handle writes & reads to total size
int update_size_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg)
{
concurrency::LockGuard g(updateLock);
// Check if there is enough to OTA Update
chr_readwrite32le(&updateExpectedSize, ctxt);
if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR && updateExpectedSize != 0) {
updateActualSize = 0;
crc.reset();
if (Update.isRunning())
Update.abort();
bool canBegin = Update.begin(updateExpectedSize, update_region);
DEBUG_MSG("Setting region %d update size %u, result %d\n", update_region, updateExpectedSize, canBegin);
if (!canBegin) {
// Indicate failure by forcing the size to 0 (client will read it back)
updateExpectedSize = 0;
} else {
// This totally breaks abstraction to up up into the app layer for this, but quick hack to make sure we only
// talk to one service during the sw update.
// DEBUG_MSG("FIXME, crufty shutdown of mesh bluetooth for sw update.");
// void stopMeshBluetoothService();
// stopMeshBluetoothService();
screen->startFirmwareUpdateScreen();
if (RadioLibInterface::instance)
RadioLibInterface::instance->disable(); // FIXME, nasty hack - the RF95 ISR/SPI code on ESP32 can fail while we
// are writing flash - shut the radio off during updates
}
}
return 0;
}
#define MAX_BLOCKSIZE_FOR_BT 512
/// Handle writes to data
int update_data_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg)
{
concurrency::LockGuard g(updateLock);
static uint8_t
data[MAX_BLOCKSIZE_FOR_BT]; // we temporarily copy here because I'm worried that a fast sender might be able overwrite srcbuf
uint16_t len = 0;
auto rc = ble_hs_mbuf_to_flat(ctxt->om, data, sizeof(data), &len);
assert(rc == 0);
// DEBUG_MSG("Writing %u\n", len);
crc.update(data, len);
Update.write(data, len);
updateActualSize += len;
powerFSM.trigger(EVENT_FIRMWARE_UPDATE);
return 0;
}
/// Handle writes to crc32
int update_crc32_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg)
{
concurrency::LockGuard g(updateLock);
uint32_t expectedCRC = 0;
chr_readwrite32le(&expectedCRC, ctxt);
uint32_t actualCRC = crc.finalize();
DEBUG_MSG("expected CRC %u\n", expectedCRC);
uint8_t result = 0xff;
if (updateActualSize != updateExpectedSize) {
DEBUG_MSG("Expected %u bytes, but received %u bytes!\n", updateExpectedSize, updateActualSize);
result = 0xe1; // FIXME, use real error codes
} else if (actualCRC != expectedCRC) // Check the CRC before asking the update to happen.
{
DEBUG_MSG("Invalid CRC! expected=%u, actual=%u\n", expectedCRC, actualCRC);
result = 0xe0; // FIXME, use real error codes
} else {
if (Update.end()) {
if (update_region == U_SPIFFS) {
DEBUG_MSG("Filesystem updated!\n");
nodeDB.saveToDisk(); // Since we just wiped the filesystem, we need to save our current state
} else {
DEBUG_MSG("Appload updated, rebooting in 5 seconds!\n");
rebootAtMsec = millis() + 5000;
}
} else {
DEBUG_MSG("Error Occurred. Error #: %d\n", Update.getError());
}
result = Update.getError();
}
if (RadioLibInterface::instance)
RadioLibInterface::instance->startReceive(); // Resume radio
assert(updateResultHandle >= 0);
update_result = result;
DEBUG_MSG("BLE notify update result\n");
auto res = ble_gattc_notify(curConnectionHandle, updateResultHandle);
assert(res == 0);
return 0;
}
int update_result_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg)
{
return chr_readwrite8(&update_result, sizeof(update_result), ctxt);
}
int update_region_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg)
{
return chr_readwrite8(&update_region, sizeof(update_region), ctxt);
}
/*
See bluetooth-api.md
*/
void reinitUpdateService()
{
if (!updateLock)
updateLock = new concurrency::Lock();
auto res = ble_gatts_count_cfg(gatt_update_svcs); // assigns handles? see docstring for note about clearing the handle list
// before calling SLEEP SUPPORT
assert(res == 0);
res = ble_gatts_add_svcs(gatt_update_svcs);
assert(res == 0);
}
#endif //#ifndef USE_NEW_ESP32_BLUETOOTH
-29
View File
@@ -1,29 +0,0 @@
#ifndef USE_NEW_ESP32_BLUETOOTH
#pragma once
#include "nimble/NimbleDefs.h"
void reinitUpdateService();
#ifdef __cplusplus
extern "C" {
#endif
int update_size_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg);
int update_data_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg);
int update_result_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg);
int update_crc32_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg);
int update_region_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg);
extern const struct ble_gatt_svc_def gatt_update_svcs[];
extern const ble_uuid128_t update_result_uuid, update_region_uuid;
extern int16_t updateResultHandle;
#ifdef __cplusplus
};
#endif
#endif //#ifndef USE_NEW_ESP32_BLUETOOTH
-259
View File
@@ -1,259 +0,0 @@
#ifdef USE_NEW_ESP32_BLUETOOTH
#include "configuration.h"
#include "ESP32Bluetooth.h"
#include "BluetoothCommon.h"
#include "PowerFSM.h"
#include "sleep.h"
#include "main.h"
#include "mesh/PhoneAPI.h"
#include "mesh/mesh-pb-constants.h"
#include <NimBLEDevice.h>
//static BLEService meshBleService = BLEService(BLEUuid(MESH_SERVICE_UUID_16));
//static BLECharacteristic fromNum = BLECharacteristic(BLEUuid(FROMNUM_UUID_16));
//static BLECharacteristic fromRadio = BLECharacteristic(BLEUuid(FROMRADIO_UUID_16));
//static BLECharacteristic toRadio = BLECharacteristic(BLEUuid(TORADIO_UUID_16));
//static BLEDis bledis; // DIS (Device Information Service) helper class instance
//static BLEBas blebas; // BAS (Battery Service) helper class instance
//static BLEDfu bledfu; // DFU software update helper service
// This scratch buffer is used for various bluetooth reads/writes - but it is safe because only one bt operation can be in
// proccess at once
// static uint8_t trBytes[_max(_max(_max(_max(ToRadio_size, RadioConfig_size), User_size), MyNodeInfo_size), FromRadio_size)];
static uint8_t fromRadioBytes[FromRadio_size];
NimBLECharacteristic *FromNumCharacteristic;
NimBLEServer *bleServer;
static bool passkeyShowing;
static uint32_t doublepressed;
/**
* Subclasses can use this as a hook to provide custom notifications for their transport (i.e. bluetooth notifies)
*/
void BluetoothPhoneAPI::onNowHasData(uint32_t fromRadioNum)
{
PhoneAPI::onNowHasData(fromRadioNum);
DEBUG_MSG("BLE notify fromNum\n");
//fromNum.notify32(fromRadioNum);
uint8_t val[4];
put_le32(val, fromRadioNum);
std::string fromNumByteString(&val[0], &val[0] + sizeof(val));
FromNumCharacteristic->setValue(fromNumByteString);
FromNumCharacteristic->notify();
}
/// Check the current underlying physical link to see if the client is currently connected
bool BluetoothPhoneAPI::checkIsConnected() {
if (bleServer && bleServer->getConnectedCount() > 0) {
return true;
}
return false;
}
PhoneAPI *bluetoothPhoneAPI;
class ESP32BluetoothToRadioCallback : public NimBLECharacteristicCallbacks {
virtual void onWrite(NimBLECharacteristic *pCharacteristic) {
DEBUG_MSG("To Radio onwrite\n");
auto valueString = pCharacteristic->getValue();
bluetoothPhoneAPI->handleToRadio(reinterpret_cast<const uint8_t*>(&valueString[0]), pCharacteristic->getDataLength());
}
};
class ESP32BluetoothFromRadioCallback : public NimBLECharacteristicCallbacks {
virtual void onRead(NimBLECharacteristic *pCharacteristic) {
DEBUG_MSG("From Radio onread\n");
size_t numBytes = bluetoothPhoneAPI->getFromRadio(fromRadioBytes);
std::string fromRadioByteString(fromRadioBytes, fromRadioBytes + numBytes);
pCharacteristic->setValue(fromRadioByteString);
}
};
class ESP32BluetoothServerCallback : public NimBLEServerCallbacks {
virtual uint32_t onPassKeyRequest() {
uint32_t passkey = 0;
if (doublepressed > 0 && (doublepressed + (30 * 1000)) > millis()) {
DEBUG_MSG("User has overridden passkey\n");
passkey = defaultBLEPin;
} else {
DEBUG_MSG("Using random passkey\n");
passkey = random(
100000, 999999); // This is the passkey to be entered on peer - we pick a number >100,000 to ensure 6 digits
}
DEBUG_MSG("*** Enter passkey %d on the peer side ***\n", passkey);
powerFSM.trigger(EVENT_BLUETOOTH_PAIR);
screen->startBluetoothPinScreen(passkey);
passkeyShowing = true;
return passkey;
}
virtual void onAuthenticationComplete(ble_gap_conn_desc *desc) {
DEBUG_MSG("BLE authentication complete\n");
if (passkeyShowing) {
passkeyShowing = false;
screen->stopBluetoothPinScreen();
}
}
};
static ESP32BluetoothToRadioCallback *toRadioCallbacks;
static ESP32BluetoothFromRadioCallback *fromRadioCallbacks;
void ESP32Bluetooth::shutdown()
{
// Shutdown bluetooth for minimum power draw
DEBUG_MSG("Disable bluetooth\n");
//Bluefruit.Advertising.stop();
}
void ESP32Bluetooth::setup()
{
// Initialise the Bluefruit module
DEBUG_MSG("Initialise the ESP32 bluetooth module\n");
//Bluefruit.autoConnLed(false);
//Bluefruit.begin();
// Set the advertised device name (keep it short!)
//Bluefruit.setName(getDeviceName());
// Set the connect/disconnect callback handlers
//Bluefruit.Periph.setConnectCallback(connect_callback);
//Bluefruit.Periph.setDisconnectCallback(disconnect_callback);
// Configure and Start the Device Information Service
DEBUG_MSG("Configuring the Device Information Service\n");
// FIXME, we should set a mfg string based on our HW_VENDOR enum
// bledis.setManufacturer(HW_VENDOR);
//bledis.setModel(optstr(HW_VERSION));
//bledis.setFirmwareRev(optstr(APP_VERSION));
//bledis.begin();
// Start the BLE Battery Service and set it to 100%
//DEBUG_MSG("Configuring the Battery Service\n");
//blebas.begin();
//blebas.write(0); // Unknown battery level for now
//bledfu.begin(); // Install the DFU helper
// Setup the Heart Rate Monitor service using
// BLEService and BLECharacteristic classes
DEBUG_MSG("Configuring the Mesh bluetooth service\n");
//setupMeshService();
// Supposedly debugging works with soft device if you disable advertising
//if (isSoftDeviceAllowed) {
// Setup the advertising packet(s)
// DEBUG_MSG("Setting up the advertising payload(s)\n");
// startAdv();
// DEBUG_MSG("Advertising\n");
//}
//NimBLEDevice::deleteAllBonds();
NimBLEDevice::init(getDeviceName());
NimBLEDevice::setPower(ESP_PWR_LVL_P9);
NimBLEDevice::setSecurityAuth(true, true, true);
NimBLEDevice::setSecurityIOCap(BLE_HS_IO_DISPLAY_ONLY);
bleServer = NimBLEDevice::createServer();
ESP32BluetoothServerCallback *serverCallbacks = new ESP32BluetoothServerCallback();
bleServer->setCallbacks(serverCallbacks);
NimBLEService *bleService = bleServer->createService(MESH_SERVICE_UUID);
//NimBLECharacteristic *pNonSecureCharacteristic = bleService->createCharacteristic("1234", NIMBLE_PROPERTY::READ );
//NimBLECharacteristic *pSecureCharacteristic = bleService->createCharacteristic("1235", NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::READ_ENC | NIMBLE_PROPERTY::READ_AUTHEN);
//define the characteristics that the app is looking for
NimBLECharacteristic *ToRadioCharacteristic = bleService->createCharacteristic(TORADIO_UUID, NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::WRITE_AUTHEN | NIMBLE_PROPERTY::WRITE_ENC);
NimBLECharacteristic *FromRadioCharacteristic = bleService->createCharacteristic(FROMRADIO_UUID, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::READ_AUTHEN | NIMBLE_PROPERTY::READ_ENC);
FromNumCharacteristic = bleService->createCharacteristic(FROMNUM_UUID, NIMBLE_PROPERTY::NOTIFY | NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::READ_AUTHEN | NIMBLE_PROPERTY::READ_ENC);
bluetoothPhoneAPI = new BluetoothPhoneAPI();
toRadioCallbacks = new ESP32BluetoothToRadioCallback();
ToRadioCharacteristic->setCallbacks(toRadioCallbacks);
fromRadioCallbacks = new ESP32BluetoothFromRadioCallback();
FromRadioCharacteristic->setCallbacks(fromRadioCallbacks);
//uint8_t val[4];
//uint32_t zero = 0;
//put_le32(val, zero);
//std::string fromNumByteString(&val[0], &val[0] + sizeof(val));
//FromNumCharacteristic->setValue(fromNumByteString);
bleService->start();
//pNonSecureCharacteristic->setValue("Hello Non Secure BLE");
//pSecureCharacteristic->setValue("Hello Secure BLE");
//FromRadioCharacteristic->setValue("FromRadioString");
//ToRadioCharacteristic->setCallbacks()
NimBLEAdvertising *pAdvertising = NimBLEDevice::getAdvertising();
pAdvertising->addServiceUUID(MESH_SERVICE_UUID);
pAdvertising->start();
}
/// Given a level between 0-100, update the BLE attribute
void updateBatteryLevel(uint8_t level)
{
//blebas.write(level);
}
void ESP32Bluetooth::clearBonds()
{
DEBUG_MSG("Clearing bluetooth bonds!\n");
//bond_print_list(BLE_GAP_ROLE_PERIPH);
//bond_print_list(BLE_GAP_ROLE_CENTRAL);
//Bluefruit.Periph.clearBonds();
//Bluefruit.Central.clearBonds();
}
void clearNVS() {
NimBLEDevice::deleteAllBonds();
ESP.restart();
}
void disablePin() {
DEBUG_MSG("User Override, disabling bluetooth pin requirement\n");
// keep track of when it was pressed, so we know it was within X seconds
// Flash the LED
setLed(true);
delay(100);
setLed(false);
delay(100);
setLed(true);
delay(100);
setLed(false);
delay(100);
setLed(true);
delay(100);
setLed(false);
doublepressed = millis();
}
#endif
-33
View File
@@ -1,33 +0,0 @@
#ifdef USE_NEW_ESP32_BLUETOOTH
#pragma once
extern uint16_t fromNumValHandle;
class BluetoothPhoneAPI : public PhoneAPI
{
protected:
/**
* Subclasses can use this as a hook to provide custom notifications for their transport (i.e. bluetooth notifies)
*/
virtual void onNowHasData(uint32_t fromRadioNum) override;
/// Check the current underlying physical link to see if the client is currently connected
virtual bool checkIsConnected() override;
};
extern PhoneAPI *bluetoothPhoneAPI;
class ESP32Bluetooth
{
public:
void setup();
void shutdown();
void clearBonds();
};
void setBluetoothEnable(bool on);
void clearNVS();
void disablePin();
#endif
-73
View File
@@ -1,73 +0,0 @@
#ifndef USE_NEW_ESP32_BLUETOOTH
#include "BluetoothSoftwareUpdate.h"
// NRF52 wants these constants as byte arrays
// Generated here https://yupana-engineering.com/online-uuid-to-c-array-converter - but in REVERSE BYTE ORDER
// "cb0b9a0b-a84c-4c0d-bdbb-442e3144ee30"
const ble_uuid128_t update_service_uuid =
BLE_UUID128_INIT(0x30, 0xee, 0x44, 0x31, 0x2e, 0x44, 0xbb, 0xbd, 0x0d, 0x4c, 0x4c, 0xa8, 0x0b, 0x9a, 0x0b, 0xcb);
// "e74dd9c0-a301-4a6f-95a1-f0e1dbea8e1e" write|read
const ble_uuid128_t update_size_uuid =
BLE_UUID128_INIT(0x1e, 0x8e, 0xea, 0xdb, 0xe1, 0xf0, 0xa1, 0x95, 0x6f, 0x4a, 0x01, 0xa3, 0xc0, 0xd9, 0x4d, 0xe7);
// "e272ebac-d463-4b98-bc84-5cc1a39ee517" write
const ble_uuid128_t update_data_uuid =
BLE_UUID128_INIT(0x17, 0xe5, 0x9e, 0xa3, 0xc1, 0x5c, 0x84, 0xbc, 0x98, 0x4b, 0x63, 0xd4, 0xac, 0xeb, 0x72, 0xe2);
// "4826129c-c22a-43a3-b066-ce8f0d5bacc6" write
const ble_uuid128_t update_crc32_uuid =
BLE_UUID128_INIT(0xc6, 0xac, 0x5b, 0x0d, 0x8f, 0xce, 0x66, 0xb0, 0xa3, 0x43, 0x2a, 0xc2, 0x9c, 0x12, 0x26, 0x48);
// "5e134862-7411-4424-ac4a-210937432c77" read|notify
const ble_uuid128_t update_result_uuid =
BLE_UUID128_INIT(0x77, 0x2c, 0x43, 0x37, 0x09, 0x21, 0x4a, 0xac, 0x24, 0x44, 0x11, 0x74, 0x62, 0x48, 0x13, 0x5e);
// "5e134862-7411-4424-ac4a-210937432c67" write
const ble_uuid128_t update_region_uuid =
BLE_UUID128_INIT(0x67, 0x2c, 0x43, 0x37, 0x09, 0x21, 0x4a, 0xac, 0x24, 0x44, 0x11, 0x74, 0x62, 0x48, 0x13, 0x5e);
const struct ble_gatt_svc_def gatt_update_svcs[] = {
{
/*** Service: Security test. */
.type = BLE_GATT_SVC_TYPE_PRIMARY,
.uuid = &update_service_uuid.u,
.characteristics =
(struct ble_gatt_chr_def[]){{
.uuid = &update_size_uuid.u,
.access_cb = update_size_callback,
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_WRITE_AUTHEN | BLE_GATT_CHR_F_READ |
BLE_GATT_CHR_F_READ_AUTHEN,
},
{
.uuid = &update_data_uuid.u,
.access_cb = update_data_callback,
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_WRITE_AUTHEN,
},
{
.uuid = &update_crc32_uuid.u,
.access_cb = update_crc32_callback,
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_WRITE_AUTHEN,
},
{
.uuid = &update_result_uuid.u,
.access_cb = update_result_callback,
.flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_AUTHEN | BLE_GATT_CHR_F_NOTIFY,
},
{
.uuid = &update_region_uuid.u,
.access_cb = update_region_callback,
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_WRITE_AUTHEN,
},
{
0, /* No more characteristics in this service. */
}},
},
{
0, /* No more services. */
},
};
#endif //#ifndef USE_NEW_ESP32_BLUETOOTH
+296 -111
View File
@@ -59,98 +59,192 @@ bool GPS::getACK(uint8_t c, uint8_t i) {
}
}
/**
* @brief
* @note New method, this method can wait for the specified class and message ID, and return the payload
* @param *buffer: The message buffer, if there is a response payload message, it will be returned through the buffer parameter
* @param size: size of buffer
* @param requestedClass: request class constant
* @param requestedID: request message ID constant
* @retval length of payload message
*/
int GPS::getAck(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t requestedID)
{
uint16_t ubxFrameCounter = 0;
uint32_t startTime = millis();
uint16_t needRead;
while (millis() - startTime < 800) {
while (_serial_gps->available()) {
int c = _serial_gps->read();
switch (ubxFrameCounter) {
case 0:
//ubxFrame 'μ'
if (c == 0xB5) {
ubxFrameCounter++;
}
break;
case 1:
//ubxFrame 'b'
if (c == 0x62) {
ubxFrameCounter++;
} else {
ubxFrameCounter = 0;
}
break;
case 2:
//Class
if (c == requestedClass) {
ubxFrameCounter++;
} else {
ubxFrameCounter = 0;
}
break;
case 3:
//Message ID
if (c == requestedID) {
ubxFrameCounter++;
} else {
ubxFrameCounter = 0;
}
break;
case 4:
//Payload lenght lsb
needRead = c;
ubxFrameCounter++;
break;
case 5:
//Payload lenght msb
needRead |= (c << 8);
ubxFrameCounter++;
break;
case 6:
// Check for buffer overflow
if (needRead >= size) {
ubxFrameCounter = 0;
break;
}
if (_serial_gps->readBytes(buffer, needRead) != needRead) {
ubxFrameCounter = 0;
} else {
// return payload lenght
return needRead;
}
break;
default:
break;
}
}
}
return 0;
}
bool GPS::setupGPS()
{
if (_serial_gps && !didSerialInit) {
didSerialInit = true;
#ifdef ARCH_ESP32
// In esp32 framework, setRxBufferSize needs to be initialized before Serial
_serial_gps->setRxBufferSize(2048); // the default is 256
#endif
// ESP32 has a special set of parameters vs other arduino ports
#if defined(GPS_RX_PIN) && !defined(NO_ESP32)
#if defined(GPS_RX_PIN) && defined(ARCH_ESP32)
_serial_gps->begin(GPS_BAUDRATE, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN);
#else
_serial_gps->begin(GPS_BAUDRATE);
#endif
#ifndef NO_ESP32
_serial_gps->setRxBufferSize(2048); // the default is 256
#endif
#ifdef TTGO_T_ECHO
// Switch to 9600 baud, then close and reopen port
_serial_gps->end();
delay(250);
_serial_gps->begin(4800);
delay(250);
_serial_gps->write("$PCAS01,1*1D\r\n");
delay(250);
_serial_gps->end();
delay(250);
_serial_gps->begin(9600);
delay(250);
// Initialize the L76K Chip, use GPS + GLONASS
_serial_gps->write("$PCAS04,5*1C\r\n");
delay(250);
// only ask for RMC and GGA
_serial_gps->write("$PCAS03,1,0,0,0,1,0,0,0,0,0,,,0,0*02\r\n");
delay(250);
// Switch to Vehicle Mode, since SoftRF enables Aviation < 2g
_serial_gps->write("$PCAS11,3*1E\r\n");
delay(250);
#endif
#ifdef GPS_UBLOX
delay(250);
// Set the UART port to output NMEA only
byte _message_nmea[] = {0xB5, 0x62, 0x06, 0x00, 0x14, 0x00, 0x01, 0x00, 0x00, 0x00, 0xC0, 0x08, 0x00, 0x00,
0x80, 0x25, 0x00, 0x00, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0xAF};
_serial_gps->write(_message_nmea, sizeof(_message_nmea));
if (!getACK(0x06, 0x00)) {
DEBUG_MSG("WARNING: Unable to enable NMEA Mode.\n");
return true;
}
// disable GGL
byte _message_GGL[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x05, 0x3A};
_serial_gps->write(_message_GGL, sizeof(_message_GGL));
if (!getACK(0x06, 0x01)) {
DEBUG_MSG("WARNING: Unable to disable NMEA GGL.\n");
return true;
/*
* T-Beam-S3-Core will be preset to use gps Probe here, and other boards will not be changed first
*/
gnssModel = probe();
if(gnssModel == GNSS_MODEL_MTK){
/*
* t-beam-s3-core uses the same L76K GNSS module as t-echo.
* Unlike t-echo, L76K uses 9600 baud rate for communication by default.
* */
// _serial_gps->begin(9600); //The baud rate of 9600 has been initialized at the beginning of setupGPS, this line is the redundant part
// delay(250);
// Initialize the L76K Chip, use GPS + GLONASS
_serial_gps->write("$PCAS04,5*1C\r\n");
delay(250);
// only ask for RMC and GGA
_serial_gps->write("$PCAS03,1,0,0,0,1,0,0,0,0,0,,,0,0*02\r\n");
delay(250);
// Switch to Vehicle Mode, since SoftRF enables Aviation < 2g
_serial_gps->write("$PCAS11,3*1E\r\n");
delay(250);
}else if(gnssModel == GNSS_MODEL_UBLOX){
/*
tips: NMEA Only should not be set here, otherwise initializing Ublox gnss module again after
setting will not output command messages in UART1, resulting in unrecognized module information
// Set the UART port to output NMEA only
byte _message_nmea[] = {0xB5, 0x62, 0x06, 0x00, 0x14, 0x00, 0x01, 0x00, 0x00, 0x00, 0xC0, 0x08, 0x00, 0x00,
0x80, 0x25, 0x00, 0x00, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0xAF};
_serial_gps->write(_message_nmea, sizeof(_message_nmea));
if (!getACK(0x06, 0x00)) {
DEBUG_MSG("WARNING: Unable to enable NMEA Mode.\n");
return true;
}
*/
// ublox-M10S can be compatible with UBLOX traditional protocol, so the following sentence settings are also valid
// disable GGL
byte _message_GGL[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x05, 0x3A};
_serial_gps->write(_message_GGL, sizeof(_message_GGL));
if (!getACK(0x06, 0x01)) {
DEBUG_MSG("WARNING: Unable to disable NMEA GGL.\n");
return true;
}
// disable GSA
byte _message_GSA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x02, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x06, 0x41};
_serial_gps->write(_message_GSA, sizeof(_message_GSA));
if (!getACK(0x06, 0x01)) {
DEBUG_MSG("WARNING: Unable to disable NMEA GSA.\n");
return true;
}
// disable GSV
byte _message_GSV[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x03, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x07, 0x48};
_serial_gps->write(_message_GSV, sizeof(_message_GSV));
if (!getACK(0x06, 0x01)) {
DEBUG_MSG("WARNING: Unable to disable NMEA GSV.\n");
return true;
}
// disable VTG
byte _message_VTG[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x05, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x09, 0x56};
_serial_gps->write(_message_VTG, sizeof(_message_VTG));
if (!getACK(0x06, 0x01)) {
DEBUG_MSG("WARNING: Unable to disable NMEA VTG.\n");
return true;
}
// enable RMC
byte _message_RMC[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x09, 0x54};
_serial_gps->write(_message_RMC, sizeof(_message_RMC));
if (!getACK(0x06, 0x01)) {
DEBUG_MSG("WARNING: Unable to enable NMEA RMC.\n");
return true;
}
// enable GGA
byte _message_GGA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x05, 0x38};
_serial_gps->write(_message_GGA, sizeof(_message_GGA));
if (!getACK(0x06, 0x01)) {
DEBUG_MSG("WARNING: Unable to enable NMEA GGA.\n");
}
}
// disable GSA
byte _message_GSA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x02, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x06, 0x41};
_serial_gps->write(_message_GSA, sizeof(_message_GSA));
if (!getACK(0x06, 0x01)) {
DEBUG_MSG("WARNING: Unable to disable NMEA GSA.\n");
return true;
}
// disable GSV
byte _message_GSV[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x03, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x07, 0x48};
_serial_gps->write(_message_GSV, sizeof(_message_GSV));
if (!getACK(0x06, 0x01)) {
DEBUG_MSG("WARNING: Unable to disable NMEA GSV.\n");
return true;
}
// disable VTG
byte _message_VTG[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x05, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x09, 0x56};
_serial_gps->write(_message_VTG, sizeof(_message_VTG));
if (!getACK(0x06, 0x01)) {
DEBUG_MSG("WARNING: Unable to disable NMEA VTG.\n");
return true;
}
// enable RMC
byte _message_RMC[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x09, 0x54};
_serial_gps->write(_message_RMC, sizeof(_message_RMC));
if (!getACK(0x06, 0x01)) {
DEBUG_MSG("WARNING: Unable to enable NMEA RMC.\n");
return true;
}
// enable GGA
byte _message_GGA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x05, 0x38};
_serial_gps->write(_message_GGA, sizeof(_message_GGA));
if (!getACK(0x06, 0x01)) DEBUG_MSG("WARNING: Unable to enable NMEA GGA.\n");
#endif
}
return true;
@@ -271,16 +365,7 @@ uint32_t GPS::getWakeTime() const
if (t == UINT32_MAX)
return t; // already maxint
if (t == 0)
t = (config.device.role == Config_DeviceConfig_Role_Router)
? 5 * 60
: 15 * 60; // Allow up to 15 mins for each attempt (probably will be much
// less if we can find sats) or less if a router
t *= 1000; // msecs
return t;
return t * 1000;
}
/** Get how long we should sleep between aqusition attempts in msecs
@@ -288,21 +373,15 @@ uint32_t GPS::getWakeTime() const
uint32_t GPS::getSleepTime() const
{
uint32_t t = config.position.gps_update_interval;
bool gps_disabled = config.position.gps_disabled;
bool gps_enabled = config.position.gps_enabled;
if (gps_disabled)
if (!gps_enabled)
t = UINT32_MAX; // Sleep forever now
if (t == UINT32_MAX)
return t; // already maxint
if (t == 0) // default - unset in preferences
t = (config.device.role == Config_DeviceConfig_Role_Router) ? 24 * 60 * 60
: 2 * 60; // 2 mins or once per day for routers
t *= 1000;
return t;
return t * 1000;
}
void GPS::publishUpdate()
@@ -311,7 +390,7 @@ void GPS::publishUpdate()
shouldPublish = false;
// In debug logs, identify position by @timestamp:stage (stage 2 = publish)
DEBUG_MSG("publishing pos@%x:2, hasVal=%d, GPSlock=%d\n", p.pos_timestamp, hasValidLocation, hasLock());
DEBUG_MSG("publishing pos@%x:2, hasVal=%d, GPSlock=%d\n", p.timestamp, hasValidLocation, hasLock());
// Notify any status instances that are observing us
const meshtastic::GPSStatus status = meshtastic::GPSStatus(hasValidLocation, isConnected(), p);
@@ -325,14 +404,14 @@ int32_t GPS::runOnce()
// if we have received valid NMEA claim we are connected
setConnected();
} else {
#ifdef GPS_UBLOX
// reset the GPS on next bootup
if(devicestate.did_gps_reset && (millis() > 60000) && !hasFlow()) {
DEBUG_MSG("GPS is not communicating, trying factory reset on next bootup.\n");
devicestate.did_gps_reset = false;
nodeDB.saveToDisk();
if(gnssModel == GNSS_MODEL_UBLOX){
// reset the GPS on next bootup
if(devicestate.did_gps_reset && (millis() > 60000) && !hasFlow()) {
DEBUG_MSG("GPS is not communicating, trying factory reset on next bootup.\n");
devicestate.did_gps_reset = false;
nodeDB.saveDeviceStateToDisk();
}
}
#endif
}
// If we are overdue for an update, turn on the GPS and at least publish the current status
@@ -432,17 +511,123 @@ int GPS::prepareDeepSleep(void *unused)
return 0;
}
#ifndef NO_GPS
GnssModel_t GPS::probe()
{
// return immediately if the model is set by the variant.h file
#ifdef GPS_UBLOX
return GNSS_MODEL_UBLOX;
#elif defined(GPS_L76K)
return GNSS_MODEL_MTK;
#else
// we use autodetect, only T-BEAM S3 for now...
uint8_t buffer[256];
/*
* The GNSS module information variable is temporarily placed inside the function body,
* if it needs to be used elsewhere, it can be moved to the outside
* */
struct uBloxGnssModelInfo info ;
memset(&info, 0, sizeof(struct uBloxGnssModelInfo));
// Close all NMEA sentences , Only valid for MTK platform
_serial_gps->write("$PCAS03,0,0,0,0,0,0,0,0,0,0,,,0,0*02\r\n");
delay(20);
// Get version information
_serial_gps->write("$PCAS06,0*1B\r\n");
uint32_t startTimeout = millis() + 500;
while (millis() < startTimeout) {
if (_serial_gps->available()) {
String ver = _serial_gps->readStringUntil('\r');
// Get module info , If the correct header is returned,
// it can be determined that it is the MTK chip
int index = ver.indexOf("$");
if(index != -1){
ver = ver.substring(index);
if (ver.startsWith("$GPTXT,01,01,02")) {
DEBUG_MSG("L76K GNSS init succeeded, using L76K GNSS Module\n");
return GNSS_MODEL_MTK;
}
}
}
}
uint8_t cfg_rate[] = {0xB5, 0x62, 0x06, 0x08, 0x00, 0x00, 0x0E, 0x30};
_serial_gps->write(cfg_rate, sizeof(cfg_rate));
// Check that the returned response class and message ID are correct
if (!getAck(buffer, 256, 0x06, 0x08)) {
DEBUG_MSG("Warning: Failed to find UBlox & MTK GNSS Module\n");
return GNSS_MODEL_UNKONW;
}
// Get Ublox gnss module hardware and software info
uint8_t cfg_get_hw[] = {0xB5, 0x62, 0x0A, 0x04, 0x00, 0x00, 0x0E, 0x34};
_serial_gps->write(cfg_get_hw, sizeof(cfg_get_hw));
uint16_t len = getAck(buffer, 256, 0x0A, 0x04);
if (len) {
uint16_t position = 0;
for (int i = 0; i < 30; i++) {
info.swVersion[i] = buffer[position];
position++;
}
for (int i = 0; i < 10; i++) {
info.hwVersion[i] = buffer[position];
position++;
}
while (len >= position + 30) {
for (int i = 0; i < 30; i++) {
info.extension[info.extensionNo][i] = buffer[position];
position++;
}
info.extensionNo++;
if (info.extensionNo > 9)
break;
}
DEBUG_MSG("Module Info : \n");
DEBUG_MSG("Soft version: %s\n",info.swVersion);
DEBUG_MSG("Hard version: %s\n",info.hwVersion);
DEBUG_MSG("Extensions:%d\n",info.extensionNo);
for (int i = 0; i < info.extensionNo; i++) {
DEBUG_MSG(" %s\n",info.extension[i]);
}
memset(buffer,0,sizeof(buffer));
//tips: extensionNo field is 0 on some 6M GNSS modules
for (int i = 0; i < info.extensionNo; ++i) {
if (!strncmp(info.extension[i], "OD=", 3)) {
strcpy((char *)buffer, &(info.extension[i][3]));
DEBUG_MSG("GetModel:%s\n",(char *)buffer);
}
}
}
if (strlen((char*)buffer)) {
DEBUG_MSG("UBlox GNSS init succeeded, using UBlox %s GNSS Module\n" , buffer);
}else{
DEBUG_MSG("UBlox GNSS init succeeded, using UBlox GNSS Module\n");
}
return GNSS_MODEL_UBLOX;
#endif
}
#if HAS_GPS
#include "NMEAGPS.h"
#endif
GPS *createGps()
{
#ifdef NO_GPS
#if !HAS_GPS
return nullptr;
#else
if (!config.position.gps_disabled) {
if (config.position.gps_enabled) {
#ifdef GPS_ALTITUDE_HAE
DEBUG_MSG("Using HAE altitude model\n");
#else
+22
View File
@@ -4,6 +4,20 @@
#include "Observer.h"
#include "concurrency/OSThread.h"
struct uBloxGnssModelInfo {
char swVersion[30];
char hwVersion[10];
uint8_t extensionNo;
char extension[10][30];
} ;
typedef enum{
GNSS_MODEL_MTK,
GNSS_MODEL_UBLOX,
GNSS_MODEL_UNKONW,
}GnssModel_t;
// Generate a string representation of DOP
const char *getDOPString(uint32_t dop);
@@ -146,6 +160,14 @@ class GPS : private concurrency::OSThread
void publishUpdate();
virtual int32_t runOnce() override;
// Get GNSS model
GnssModel_t probe();
int getAck(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t requestedID);
protected:
GnssModel_t gnssModel = GNSS_MODEL_UNKONW;
};
// Creates an instance of the GPS class.
+1 -1
View File
@@ -379,7 +379,7 @@ float GeoCoord::latLongToMeter(double lat_a, double lng_a, double lat_b, double
* Latitude of the second point
* @param lon2
* Longitude of the second point
* @return Bearing between the two points in radians. A value of 0 means due
* @return Bearing from point 1 to point 2 in radians. A value of 0 means due
* north.
*/
float GeoCoord::bearing(double lat1, double lon1, double lat2, double lon2)
+17 -13
View File
@@ -19,14 +19,21 @@ static int32_t toDegInt(RawDegrees d)
bool NMEAGPS::factoryReset()
{
#ifdef GPS_UBLOX
#ifdef PIN_GPS_REINIT
//The L76K GNSS on the T-Echo requires the RESET pin to be pulled LOW
digitalWrite(PIN_GPS_REINIT, 0);
pinMode(PIN_GPS_REINIT, OUTPUT);
delay(150); //The L76K datasheet calls for at least 100MS delay
digitalWrite(PIN_GPS_REINIT, 1);
#endif
// send the UBLOX Factory Reset Command regardless of detect state, something is very wrong, just assume it's UBLOX.
// Factory Reset
byte _message_reset[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF,
0xFB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0x00, 0x00, 0x17, 0x2B, 0x7E};
_serial_gps->write(_message_reset,sizeof(_message_reset));
delay(1000);
#endif
return true;
}
@@ -155,7 +162,7 @@ bool NMEAGPS::lookForLocation()
return false;
}
p.location_source = Position_LocSource_LOCSRC_GPS_INTERNAL;
p.location_source = Position_LocSource_LOC_INTERNAL;
// Dilution of precision (an accuracy metric) is reported in 10^2 units, so we need to scale down when we use it
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
@@ -176,8 +183,8 @@ bool NMEAGPS::lookForLocation()
p.latitude_i = toDegInt(loc.lat);
p.longitude_i = toDegInt(loc.lng);
p.alt_geoid_sep = reader.geoidHeight.meters();
p.altitude_hae = reader.altitude.meters() + p.alt_geoid_sep;
p.altitude_geoidal_separation = reader.geoidHeight.meters();
p.altitude_hae = reader.altitude.meters() + p.altitude_geoidal_separation;
p.altitude = reader.altitude.meters();
p.fix_quality = fixQual;
@@ -194,7 +201,7 @@ bool NMEAGPS::lookForLocation()
t.tm_mon = reader.date.month() - 1;
t.tm_year = reader.date.year() - 1900;
t.tm_isdst = false;
p.pos_timestamp = mktime(&t);
p.timestamp = mktime(&t);
// Nice to have, if available
if (reader.satellites.isUpdated()) {
@@ -210,13 +217,10 @@ bool NMEAGPS::lookForLocation()
}
}
/*
// REDUNDANT?
// expect gps pos lat=37.520825, lon=-122.309162, alt=158
DEBUG_MSG("new NMEA GPS pos lat=%f, lon=%f, alt=%d, dop=%g, heading=%f\n",
latitude * 1e-7, longitude * 1e-7, altitude, dop * 1e-2,
heading * 1e-5);
*/
if (reader.speed.isUpdated() && reader.speed.isValid()) {
p.ground_speed = reader.speed.kmph();
}
return true;
}
+5 -5
View File
@@ -47,8 +47,8 @@ void readFromRTC()
rtc.begin();
auto tc = rtc.getDateTime();
tm t;
t.tm_year = tc.year;
t.tm_mon = tc.month;
t.tm_year = tc.year - 1900;
t.tm_mon = tc.month - 1;
t.tm_mday = tc.day;
t.tm_hour = tc.hour;
t.tm_min = tc.minute;
@@ -112,15 +112,15 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
PCF8563_Class rtc;
rtc.begin();
tm *t = localtime(&tv->tv_sec);
rtc.setDateTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_wday, t->tm_hour, t->tm_min, t->tm_sec);
rtc.setDateTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
DEBUG_MSG("PCF8563_RTC setDateTime %02d-%02d-%02d %02d:%02d:%02d %ld\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, tv->tv_sec);
}
#elif !defined(NO_ESP32)
#elif defined(ARCH_ESP32)
settimeofday(tv, NULL);
#endif
// nrf52 doesn't have a readable RTC (yet - software not written)
#if defined(PORTDUINO) || !defined(NO_ESP32) || defined(RV3028_RTC) || defined(PCF8563_RTC)
#ifdef HAS_RTC
readFromRTC();
#endif
+20 -28
View File
@@ -1,6 +1,6 @@
#include "configuration.h"
#ifdef HAS_EINK
#ifdef USE_EINK
#include "main.h"
#include "EInkDisplay2.h"
#include "SPILock.h"
@@ -31,6 +31,11 @@
//4.2 inch 300x400 - GxEPD2_420_M01
#define TECHO_DISPLAY_MODEL GxEPD2_420_M01
#elif defined(M5_COREINK)
//M5Stack CoreInk
//1.54 inch 200x200 - GxEPD2_154_M09
#define TECHO_DISPLAY_MODEL GxEPD2_154_M09
#endif
GxEPD2_BW<TECHO_DISPLAY_MODEL, TECHO_DISPLAY_MODEL::HEIGHT> *adafruitDisplay;
@@ -58,6 +63,12 @@ EInkDisplay::EInkDisplay(uint8_t address, int sda, int scl)
//GxEPD2_420_M01
setGeometry(GEOMETRY_RAWMODE, 300, 400);
#elif defined(M5_COREINK)
//M5Stack_CoreInk 200x200
//1.54 inch 200x200 - GxEPD2_154_M09
setGeometry(GEOMETRY_RAWMODE, EPD_HEIGHT, EPD_WIDTH);
#endif
// setGeometry(GEOMETRY_RAWMODE, 128, 64); // old resolution
// setGeometry(GEOMETRY_128_64); // We originally used this because I wasn't sure if rawmode worked - it does
@@ -108,7 +119,7 @@ bool EInkDisplay::forceDisplay(uint32_t msecLimit)
// 4.2 inch 300x400 - GxEPD2_420_M01
//adafruitDisplay->nextPage();
#elif defined(PCA10059)
#elif defined(PCA10059) || defined(M5_COREINK)
adafruitDisplay->nextPage();
#endif
@@ -180,35 +191,10 @@ bool EInkDisplay::connect()
adafruitDisplay->init(115200, true, 10, false, SPI1, SPISettings(4000000, MSBFIRST, SPI_MODE0));
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
adafruitDisplay->setRotation(3);
//For 1.54, 2.9 and 4.2
//adafruitDisplay->setRotation(1);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
//adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
} else {
(void)adafruitDisplay;
}
@@ -221,6 +207,12 @@ bool EInkDisplay::connect()
adafruitDisplay->setRotation(3);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
}
#elif defined(M5_COREINK)
auto lowLevel = new TECHO_DISPLAY_MODEL(PIN_EINK_CS, PIN_EINK_DC, PIN_EINK_RES, PIN_EINK_BUSY);
adafruitDisplay = new GxEPD2_BW<TECHO_DISPLAY_MODEL, TECHO_DISPLAY_MODEL::HEIGHT>(*lowLevel);
adafruitDisplay->init(115200, true, 40, false, SPI, SPISettings(4000000, MSBFIRST, SPI_MODE0));
adafruitDisplay->setRotation(0);
adafruitDisplay->setPartialWindow(0, 0, EPD_WIDTH, EPD_HEIGHT);
#endif
+135 -97
View File
@@ -20,7 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "configuration.h"
#ifndef NO_SCREEN
#if HAS_SCREEN
#include <OLEDDisplay.h>
#include "GPS.h"
@@ -39,11 +39,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "target_specific.h"
#include "utils.h"
#ifndef NO_ESP32
#ifdef ARCH_ESP32
#include "esp_task_wdt.h"
#include "mesh/http/WiFiAPClient.h"
#endif
#ifdef OLED_RU
#include "fonts/OLEDDisplayFontsRU.h"
#endif
using namespace meshtastic; /** @todo remove */
extern bool loadProto(const char *filename, size_t protoSize, size_t objSize, const pb_msgdesc_t *fields, void *dest_struct);
@@ -64,7 +68,7 @@ namespace graphics
static FrameCallback normalFrames[MAX_NUM_NODES + NUM_EXTRA_FRAMES];
static uint32_t targetFramerate = IDLE_FRAMERATE;
static char btPIN[16] = "888888";
// This image definition is here instead of images.h because it's modified dynamically by the drawBattery function
uint8_t imgBattery[16] = {0xFF, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0xE7, 0x3C};
@@ -82,7 +86,7 @@ static char ourId[5];
GeoCoord geoCoord;
// OEM Config File
static const char *oemConfigFile = "/prefs/oem.proto";
static const char *oemConfigFile = "/oem/oem.proto";
OEMStore oemStore;
#ifdef SHOW_REDRAWS
@@ -94,13 +98,17 @@ static uint16_t displayWidth, displayHeight;
#define SCREEN_WIDTH displayWidth
#define SCREEN_HEIGHT displayHeight
#if defined(HAS_EINK) || defined(ILI9341_DRIVER)
#if defined(USE_EINK) || defined(ILI9341_DRIVER)
// The screen is bigger so use bigger fonts
#define FONT_SMALL ArialMT_Plain_16
#define FONT_MEDIUM ArialMT_Plain_24
#define FONT_LARGE ArialMT_Plain_24
#else
#ifdef OLED_RU
#define FONT_SMALL ArialMT_Plain_10_RU
#else
#define FONT_SMALL ArialMT_Plain_10
#endif
#define FONT_MEDIUM ArialMT_Plain_16
#define FONT_LARGE ArialMT_Plain_24
#endif
@@ -109,12 +117,10 @@ static uint16_t displayWidth, displayHeight;
#define FONT_HEIGHT_SMALL fontHeight(FONT_SMALL)
#define FONT_HEIGHT_MEDIUM fontHeight(FONT_MEDIUM)
#define FONT_HEIGHT_LARGE fontHeight(FONT_LARGE)
#define getStringCenteredX(s) ((SCREEN_WIDTH - display->getStringWidth(s)) / 2)
#ifndef SCREEN_TRANSITION_MSECS
#define SCREEN_TRANSITION_MSECS 300
#endif
/**
* Draw the icon with extra info printed around the corners
@@ -212,7 +218,7 @@ static void drawSSLScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16
display->setFont(FONT_SMALL);
display->drawString(64 + x, y, "Creating SSL certificate");
#ifndef NO_ESP32
#ifdef ARCH_ESP32
yield();
esp_task_wdt_reset();
#endif
@@ -228,38 +234,29 @@ static void drawSSLScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16
// Used when booting without a region set
static void drawWelcomeScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
display->setFont(FONT_SMALL);
display->setTextAlignment(TEXT_ALIGN_CENTER);
display->drawString(64 + x, y, "//\\ E S H T /\\ S T / C");
display->drawString(64 + x, y + FONT_HEIGHT_SMALL, getDeviceName());
display->setTextAlignment(TEXT_ALIGN_LEFT);
if ((millis() / 10000) % 2) {
display->setFont(FONT_SMALL);
display->setTextAlignment(TEXT_ALIGN_CENTER);
display->drawString(64 + x, y, "//\\ E S H T /\\ S T / C");
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->drawString(x, y + FONT_HEIGHT_SMALL * 2 - 3, "Set the region using the");
display->drawString(x, y + FONT_HEIGHT_SMALL * 3 - 3, "Meshtastic Android, iOS,");
display->drawString(x, y + FONT_HEIGHT_SMALL * 4 - 3, "Flasher or CLI client.");
} else {
display->setFont(FONT_SMALL);
display->setTextAlignment(TEXT_ALIGN_CENTER);
display->drawString(64 + x, y, "//\\ E S H T /\\ S T / C");
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->drawString(x, y + FONT_HEIGHT_SMALL * 2 - 3, "Visit meshtastic.org");
display->drawString(x, y + FONT_HEIGHT_SMALL * 3 - 3, "for more information.");
display->drawString(x, y + FONT_HEIGHT_SMALL * 4 - 3, "");
}
#ifndef NO_ESP32
#ifdef ARCH_ESP32
yield();
esp_task_wdt_reset();
#endif
}
#ifdef HAS_EINK
#ifdef USE_EINK
/// Used on eink displays while in deep sleep
static void drawSleepScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
@@ -299,8 +296,13 @@ static void drawFrameBluetooth(OLEDDisplay *display, OLEDDisplayUiState *state,
display->drawString(64 + x, FONT_HEIGHT_SMALL + y + 2, "Enter this code");
display->setFont(FONT_LARGE);
display->drawString(64 + x, 26 + y, btPIN);
auto displayPin = new String(btPIN);
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->drawString(12 + x, 26 + y, displayPin->substring(0, 3));
display->drawString(72 + x, 26 + y, displayPin->substring(3, 6));
display->setTextAlignment(TEXT_ALIGN_CENTER);
display->setFont(FONT_SMALL);
char buf[30];
const char *name = "Name: ";
@@ -317,6 +319,14 @@ static void drawFrameShutdown(OLEDDisplay *display, OLEDDisplayUiState *state, i
display->drawString(64 + x, 26 + y, "Shutting down...");
}
static void drawFrameReboot(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
display->setTextAlignment(TEXT_ALIGN_CENTER);
display->setFont(FONT_MEDIUM);
display->drawString(64 + x, 26 + y, "Rebooting...");
}
static void drawFrameFirmware(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
display->setTextAlignment(TEXT_ALIGN_CENTER);
@@ -329,9 +339,6 @@ static void drawFrameFirmware(OLEDDisplay *display, OLEDDisplayUiState *state, i
} else {
display->drawString(64 + x, FONT_HEIGHT_SMALL + y + 2, "Please wait . . ");
}
// display->setFont(FONT_LARGE);
// display->drawString(64 + x, 26 + y, btPIN);
}
/// Draw the last text message we received
@@ -516,6 +523,8 @@ static void drawGPSAltitude(OLEDDisplay *display, int16_t x, int16_t y, const GP
} else {
geoCoord.updateCoords(int32_t(gps->getLatitude()), int32_t(gps->getLongitude()), int32_t(gps->getAltitude()));
displayLine = "Altitude: " + String(geoCoord.getAltitude()) + "m";
if (config.display.units == Config_DisplayConfig_DisplayUnits_IMPERIAL)
displayLine = "Altitude: " + String(geoCoord.getAltitude() * METERS_TO_FEET) + "ft";
display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(displayLine))) / 2, y, displayLine);
}
}
@@ -534,21 +543,21 @@ static void drawGPScoordinates(OLEDDisplay *display, int16_t x, int16_t y, const
display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(displayLine))) / 2, y, displayLine);
} else {
if (gpsFormat != Config_DisplayConfig_GpsCoordinateFormat_GpsFormatDMS) {
if (gpsFormat != Config_DisplayConfig_GpsCoordinateFormat_DMS) {
char coordinateLine[22];
geoCoord.updateCoords(int32_t(gps->getLatitude()), int32_t(gps->getLongitude()), int32_t(gps->getAltitude()));
if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_GpsFormatDec) { // Decimal Degrees
if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_DEC) { // Decimal Degrees
sprintf(coordinateLine, "%f %f", geoCoord.getLatitude() * 1e-7, geoCoord.getLongitude() * 1e-7);
} else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_GpsFormatUTM) { // Universal Transverse Mercator
} else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_UTM) { // Universal Transverse Mercator
sprintf(coordinateLine, "%2i%1c %06u %07u", geoCoord.getUTMZone(), geoCoord.getUTMBand(),
geoCoord.getUTMEasting(), geoCoord.getUTMNorthing());
} else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_GpsFormatMGRS) { // Military Grid Reference System
} else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_MGRS) { // Military Grid Reference System
sprintf(coordinateLine, "%2i%1c %1c%1c %05u %05u", geoCoord.getMGRSZone(), geoCoord.getMGRSBand(),
geoCoord.getMGRSEast100k(), geoCoord.getMGRSNorth100k(), geoCoord.getMGRSEasting(),
geoCoord.getMGRSNorthing());
} else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_GpsFormatOLC) { // Open Location Code
} else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_OLC) { // Open Location Code
geoCoord.getOLCCode(coordinateLine);
} else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_GpsFormatOSGR) { // Ordnance Survey Grid Reference
} else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_OSGR) { // Ordnance Survey Grid Reference
if (geoCoord.getOSGRE100k() == 'I' || geoCoord.getOSGRN100k() == 'I') // OSGR is only valid around the UK region
sprintf(coordinateLine, "%s", "Out of Boundary");
else
@@ -595,7 +604,7 @@ class Point
void rotate(float radian)
{
float cos = cosf(radian), sin = sinf(radian);
float rx = x * cos - y * sin, ry = x * sin + y * cos;
float rx = x * cos + y * sin, ry = -x * sin + y * cos;
x = rx;
y = ry;
@@ -609,8 +618,10 @@ class Point
void scale(float f)
{
//We use -f here to counter the flip that happens
//on the y axis when drawing and rotating on screen
x *= f;
y *= f;
y *= -f;
}
};
@@ -682,16 +693,21 @@ static void drawNodeHeading(OLEDDisplay *display, int16_t compassX, int16_t comp
drawLine(display, rightArrow, tip);
}
// Draw the compass heading
static void drawCompassHeading(OLEDDisplay *display, int16_t compassX, int16_t compassY, float myHeading)
// Draw north
static void drawCompassNorth(OLEDDisplay *display, int16_t compassX, int16_t compassY, float myHeading)
{
Point N1(-0.04f, -0.65f), N2(0.04f, -0.65f);
Point N3(-0.04f, -0.55f), N4(0.04f, -0.55f);
//If north is supposed to be at the top of the compass we want rotation to be +0
if(config.display.compass_north_top)
myHeading = -0;
Point N1(-0.04f, 0.65f), N2(0.04f, 0.65f);
Point N3(-0.04f, 0.55f), N4(0.04f, 0.55f);
Point *rosePoints[] = {&N1, &N2, &N3, &N4};
for (int i = 0; i < 4; i++) {
rosePoints[i]->rotate(myHeading);
rosePoints[i]->scale(-1 * COMPASS_DIAM);
// North on compass will be negative of heading
rosePoints[i]->rotate(-myHeading);
rosePoints[i]->scale(COMPASS_DIAM);
rosePoints[i]->translate(compassX, compassY);
}
drawLine(display, N1, N3);
@@ -762,7 +778,7 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
if (ourNode && hasPosition(ourNode)) {
Position &op = ourNode->position;
float myHeading = estimatedHeading(DegD(op.latitude_i), DegD(op.longitude_i));
drawCompassHeading(display, compassX, compassY, myHeading);
drawCompassNorth(display, compassX, compassY, myHeading);
if (hasPosition(node)) {
// display direction toward node
@@ -770,17 +786,26 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
Position &p = node->position;
float d =
GeoCoord::latLongToMeter(DegD(p.latitude_i), DegD(p.longitude_i), DegD(op.latitude_i), DegD(op.longitude_i));
if (d < 2000)
snprintf(distStr, sizeof(distStr), "%.0f m", d);
else
snprintf(distStr, sizeof(distStr), "%.1f km", d / 1000);
// FIXME, also keep the guess at the operators heading and add/substract
// it. currently we don't do this and instead draw north up only.
if (config.display.units == Config_DisplayConfig_DisplayUnits_IMPERIAL) {
if (d < (2 * MILES_TO_FEET))
snprintf(distStr, sizeof(distStr), "%.0f ft", d * METERS_TO_FEET);
else
snprintf(distStr, sizeof(distStr), "%.1f mi", d * METERS_TO_FEET / MILES_TO_FEET);
} else {
if (d < 2000)
snprintf(distStr, sizeof(distStr), "%.0f m", d);
else
snprintf(distStr, sizeof(distStr), "%.1f km", d / 1000);
}
float bearingToOther =
GeoCoord::bearing(DegD(p.latitude_i), DegD(p.longitude_i), DegD(op.latitude_i), DegD(op.longitude_i));
float headingRadian = bearingToOther - myHeading;
drawNodeHeading(display, compassX, compassY, headingRadian);
GeoCoord::bearing(DegD(op.latitude_i), DegD(op.longitude_i), DegD(p.latitude_i), DegD(p.longitude_i));
// If the top of the compass is a static north then bearingToOther can be drawn on the compass directly
// If the top of the compass is not a static north we need adjust bearingToOther based on heading
if(!config.display.compass_north_top)
bearingToOther -= myHeading;
drawNodeHeading(display, compassX, compassY, bearingToOther);
}
}
if (!hasNodeHeading)
@@ -843,7 +868,7 @@ Screen::Screen(uint8_t address, int sda, int scl) : OSThread("Screen"), cmdQueue
*/
void Screen::doDeepSleep()
{
#ifdef HAS_EINK
#ifdef USE_EINK
static FrameCallback sleepFrames[] = {drawSleepScreen};
static const int sleepFrameCount = sizeof(sleepFrames) / sizeof(sleepFrames[0]);
ui.setFrames(sleepFrames, sleepFrameCount);
@@ -893,7 +918,7 @@ void Screen::setup()
displayWidth = dispdev.width();
displayHeight = dispdev.height();
ui.setTimePerTransition(SCREEN_TRANSITION_MSECS);
ui.setTimePerTransition(0);
ui.setIndicatorPosition(BOTTOM);
// Defines where the first frame is located in the bar.
@@ -922,8 +947,12 @@ void Screen::setup()
#ifdef SCREEN_MIRROR
dispdev.mirrorScreen();
#elif defined(SCREEN_FLIP_VERTICALLY)
dispdev.flipScreenVertically();
#else
// Standard behaviour is to FLIP the screen (needed on T-Beam). If this config item is set, unflip it, and thereby logically flip it.
// If you have a headache now, you're welcome.
if (!config.display.flip_screen) {
dispdev.flipScreenVertically();
}
#endif
// Get our hardware ID
@@ -935,9 +964,11 @@ void Screen::setup()
handleSetOn(true);
// On some ssd1306 clones, the first draw command is discarded, so draw it
// twice initially.
// twice initially. Skip this for EINK Displays to save a few seconds during boot
ui.update();
#ifndef USE_EINK
ui.update();
#endif
serialSinceMsec = millis();
// Subscribe to status updates
@@ -954,7 +985,7 @@ void Screen::setup()
void Screen::forceDisplay()
{
// Nasty hack to force epaper updates for 'key' frames. FIXME, cleanup.
#ifdef HAS_EINK
#ifdef USE_EINK
dispdev.forceDisplay();
#endif
}
@@ -994,7 +1025,7 @@ int32_t Screen::runOnce()
}
#ifndef DISABLE_WELCOME_UNSET
if (showingNormalScreen && config.lora.region == Config_LoRaConfig_RegionCode_Unset) {
if (showingNormalScreen && config.lora.region == Config_LoRaConfig_RegionCode_UNSET) {
setWelcomeFrames();
}
#endif
@@ -1032,6 +1063,9 @@ int32_t Screen::runOnce()
case Cmd::START_SHUTDOWN_SCREEN:
handleShutdownScreen();
break;
case Cmd::START_REBOOT_SCREEN:
handleRebootScreen();
break;
default:
DEBUG_MSG("BUG: invalid cmd\n");
}
@@ -1052,13 +1086,8 @@ int32_t Screen::runOnce()
// otherwise that breaks animations.
if (targetFramerate != IDLE_FRAMERATE && ui.getUiState()->frameState == FIXED) {
// oldFrameState = ui.getUiState()->frameState;
DEBUG_MSG("Setting idle framerate\n");
targetFramerate = IDLE_FRAMERATE;
#ifndef NO_ESP32
setCPUFast(false); // Turn up the CPU to improve screen animations
#endif
ui.setTargetFPS(targetFramerate);
forceDisplay();
}
@@ -1180,7 +1209,7 @@ void Screen::setFrames()
// call a method on debugInfoScreen object (for more details)
normalFrames[numframes++] = &Screen::drawDebugInfoSettingsTrampoline;
#ifndef NO_ESP32
#ifdef ARCH_ESP32
if (isWifiAvailable()) {
// call a method on debugInfoScreen object (for more details)
normalFrames[numframes++] = &Screen::drawDebugInfoWiFiTrampoline;
@@ -1224,6 +1253,18 @@ void Screen::handleShutdownScreen()
setFastFramerate();
}
void Screen::handleRebootScreen()
{
DEBUG_MSG("showing reboot screen\n");
showingNormalScreen = false;
static FrameCallback rebootFrames[] = {drawFrameReboot};
ui.disableAllIndicators();
ui.setFrames(rebootFrames, 1);
setFastFramerate();
}
void Screen::handleStartFirmwareUpdateScreen()
{
DEBUG_MSG("showing firmware screen\n");
@@ -1270,7 +1311,6 @@ void Screen::handleOnPress()
// If we are in a transition, the press must have bounced, drop it.
if (ui.getUiState()->frameState == FIXED) {
ui.nextFrame();
DEBUG_MSG("Setting LastScreenTransition\n");
lastScreenTransition = millis();
setFastFramerate();
}
@@ -1282,15 +1322,9 @@ void Screen::handleOnPress()
void Screen::setFastFramerate()
{
DEBUG_MSG("Setting fast framerate\n");
// We are about to start a transition so speed up fps
targetFramerate = SCREEN_TRANSITION_FRAMERATE;
#ifndef NO_ESP32
setCPUFast(true); // Turn up the CPU to improve screen animations
#endif
ui.setTargetFPS(targetFramerate);
setInterval(0); // redraw ASAP
runASAP = true;
@@ -1342,9 +1376,9 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
// Jm
void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
#ifdef HAS_WIFI
const char *wifiName = config.wifi.ssid;
const char *wifiPsw = config.wifi.psk;
#if HAS_WIFI
const char *wifiName = config.network.wifi_ssid;
const char *wifiPsw = config.network.wifi_psk;
displayedNodeNum = 0; // Not currently showing a node pane
@@ -1355,7 +1389,7 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i
if (isSoftAPForced()) {
display->drawString(x, y, String("WiFi: Software AP (Admin)"));
} else if (config.wifi.ap_mode) {
} else if (config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT || config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN) {
display->drawString(x, y, String("WiFi: Software AP"));
} else if (WiFi.status() != WL_CONNECTED) {
display->drawString(x, y, String("WiFi: Not Connected"));
@@ -1378,8 +1412,8 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i
- WL_NO_SHIELD: assigned when no WiFi shield is present;
*/
if (WiFi.status() == WL_CONNECTED || isSoftAPForced() || config.wifi.ap_mode) {
if (config.wifi.ap_mode || isSoftAPForced()) {
if (WiFi.status() == WL_CONNECTED || isSoftAPForced() || config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT || config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN) {
if (config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT || config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN || isSoftAPForced()) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "IP: " + String(WiFi.softAPIP().toString().c_str()));
// Number of connections to the AP. Default max for the esp32 is 4
@@ -1471,7 +1505,7 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i
}
} else {
if (config.wifi.ap_mode) {
if (config.network.wifi_mode== Config_NetworkConfig_WiFiMode_ACCESS_POINT || config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN) {
if ((millis() / 10000) % 2) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 2, "SSID: " + String(wifiName));
} else {
@@ -1519,26 +1553,26 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
auto mode = "";
switch (config.lora.modem_preset) {
case Config_LoRaConfig_ModemPreset_ShortSlow:
mode = "ShortSlow";
case Config_LoRaConfig_ModemPreset_SHORT_SLOW:
mode = "ShortS";
break;
case Config_LoRaConfig_ModemPreset_ShortFast:
mode = "ShortFast";
case Config_LoRaConfig_ModemPreset_SHORT_FAST:
mode = "ShortF";
break;
case Config_LoRaConfig_ModemPreset_MidSlow:
mode = "MediumSlow";
case Config_LoRaConfig_ModemPreset_MEDIUM_SLOW:
mode = "MedS";
break;
case Config_LoRaConfig_ModemPreset_MidFast:
mode = "MediumFast";
case Config_LoRaConfig_ModemPreset_MEDIUM_FAST:
mode = "MedF";
break;
case Config_LoRaConfig_ModemPreset_LongFast:
mode = "LongFast";
case Config_LoRaConfig_ModemPreset_LONG_SLOW:
mode = "LongS";
break;
case Config_LoRaConfig_ModemPreset_LongSlow:
mode = "LongSlow";
case Config_LoRaConfig_ModemPreset_LONG_FAST:
mode = "LongF";
break;
case Config_LoRaConfig_ModemPreset_VLongSlow:
mode = "VLongSlow";
case Config_LoRaConfig_ModemPreset_VERY_LONG_SLOW:
mode = "VeryL";
break;
default:
mode = "Custom";
@@ -1596,7 +1630,7 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
// Line 3
if (config.display.gps_format !=
Config_DisplayConfig_GpsCoordinateFormat_GpsFormatDMS) // if DMS then don't draw altitude
Config_DisplayConfig_GpsCoordinateFormat_DMS) // if DMS then don't draw altitude
drawGPSAltitude(display, x, y + FONT_HEIGHT_SMALL * 2, gpsStatus);
// Line 4
@@ -1612,6 +1646,9 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
// adjust Brightness cycle trough 1 to 254 as long as attachDuringLongPress is true
void Screen::adjustBrightness()
{
if (!useDisplay)
return;
if (brightness == 254) {
brightness = 0;
} else {
@@ -1665,4 +1702,5 @@ int Screen::handleUIFrameEvent(const UIFrameEvent *event)
}
} // namespace graphics
#endif // NO_SCREEN
#endif // HAS_SCREEN
+48 -12
View File
@@ -1,6 +1,8 @@
#pragma once
#ifdef NO_SCREEN
#include "configuration.h"
#if !HAS_SCREEN
#include "power.h"
namespace graphics
{
@@ -18,6 +20,7 @@ class Screen
void forceDisplay() {}
void startBluetoothPinScreen(uint32_t pin) {}
void stopBluetoothPinScreen() {}
void startRebootScreen() {}
};
}
@@ -54,6 +57,16 @@ class Screen
#define BRIGHTNESS_DEFAULT 150
#endif
// Meters to feet conversion
#ifndef METERS_TO_FEET
#define METERS_TO_FEET 3.28
#endif
// Feet to miles conversion
#ifndef MILES_TO_FEET
#define MILES_TO_FEET 5280
#endif
namespace graphics
{
@@ -165,6 +178,13 @@ class Screen : public concurrency::OSThread
enqueueCmd(cmd);
}
void startRebootScreen()
{
ScreenCmd cmd;
cmd.cmd = Cmd::START_REBOOT_SCREEN;
enqueueCmd(cmd);
}
/// Stops showing the bluetooth PIN screen.
void stopBluetoothPinScreen() { enqueueCmd(ScreenCmd{.cmd = Cmd::STOP_BLUETOOTH_PIN_SCREEN}); }
@@ -202,19 +222,34 @@ class Screen : public concurrency::OSThread
uint8_t last = LASTCHAR; // get last char
LASTCHAR = ch;
switch (last) { // conversion depnding on first UTF8-character
case 0xC2: {
SKIPREST = false;
return (uint8_t)ch;
}
case 0xC3: {
SKIPREST = false;
return (uint8_t)(ch | 0xC0);
}
switch (last) { // conversion depending on first UTF8-character
case 0xC2: {
SKIPREST = false;
return (uint8_t)ch;
}
case 0xC3: {
SKIPREST = false;
return (uint8_t)(ch | 0xC0);
}
// map UTF-8 cyrillic chars to it Windows-1251 (CP-1251) ASCII codes
// note: in this case we must use compatible font - provided ArialMT_Plain_10/16/24 by 'ThingPulse/esp8266-oled-ssd1306' library
// have empty chars for non-latin ASCII symbols
case 0xD0: {
SKIPREST = false;
if (ch == 129) return (uint8_t)(168); // Ё
if (ch > 143 && ch < 192) return (uint8_t)(ch + 48);
break;
}
case 0xD1: {
SKIPREST = false;
if (ch == 145) return (uint8_t)(184); // ё
if (ch > 127 && ch < 144) return (uint8_t)(ch + 112);
break;
}
}
// We want to strip out prefix chars for two-byte char formats
if (ch == 0xC2 || ch == 0xC3 || ch == 0x82)
if (ch == 0xC2 || ch == 0xC3 || ch == 0x82 || ch == 0xD0 || ch == 0xD1)
return (uint8_t)0;
// If we already returned an unconvertable-character symbol for this unconvertable-character sequence, return NULs for the
@@ -278,6 +313,7 @@ class Screen : public concurrency::OSThread
void handlePrint(const char *text);
void handleStartFirmwareUpdateScreen();
void handleShutdownScreen();
void handleRebootScreen();
/// Rebuilds our list of frames (screens) to default ones.
void setFrames();
@@ -315,7 +351,7 @@ class Screen : public concurrency::OSThread
SSD1306Wire dispdev;
#elif defined(ST7735_CS) || defined(ILI9341_DRIVER)
TFTDisplay dispdev;
#elif defined(HAS_EINK)
#elif defined(USE_EINK)
EInkDisplay dispdev;
#elif defined(USE_ST7567)
ST7567Wire dispdev;
+15 -5
View File
@@ -22,13 +22,23 @@ void TFTDisplay::display(void)
{
concurrency::LockGuard g(spiLock);
// FIXME - only draw bits have changed (use backbuf similar to the other displays)
// tft.drawBitmap(0, 0, buffer, 128, 64, TFT_YELLOW, TFT_BLACK);
for (uint16_t y = 0; y < displayHeight; y++) {
for (uint16_t x = 0; x < displayWidth; x++) {
uint16_t x,y;
for (y = 0; y < displayHeight; y++) {
for (x = 0; x < displayWidth; x++) {
// get src pixel in the page based ordering the OLED lib uses FIXME, super inefficent
auto isset = buffer[x + (y / 8) * displayWidth] & (1 << (y & 7));
tft.drawPixel(x, y, isset ? TFT_WHITE : TFT_BLACK);
auto dblbuf_isset = buffer_back[x + (y / 8) * displayWidth] & (1 << (y & 7));
if (isset != dblbuf_isset) {
tft.drawPixel(x, y, isset ? TFT_WHITE : TFT_BLACK);
}
}
}
// Copy the Buffer to the Back Buffer
for (y = 0; y < (displayHeight / 8); y++) {
for (x = 0; x < displayWidth; x++) {
uint16_t pos = x + y * displayWidth;
buffer_back[pos] = buffer[pos];
}
}
}
+426
View File
@@ -0,0 +1,426 @@
#include "OLEDDisplayFontsRU.h"
// Font generated or edited with the glyphEditor
const uint8_t ArialMT_Plain_10_RU[] PROGMEM = {
0x0A, // Width: 10
0x0D, // Height: 13
0x20, // First char: 32
0xE0, // Number of chars: 224
// Jump Table:
0xFF, 0xFF, 0x00, 0x0A, // 32
0x00, 0x00, 0x04, 0x03, // 33
0x00, 0x04, 0x05, 0x04, // 34
0x00, 0x09, 0x09, 0x06, // 35
0x00, 0x12, 0x0A, 0x06, // 36
0x00, 0x1C, 0x10, 0x09, // 37
0x00, 0x2C, 0x0E, 0x08, // 38
0x00, 0x3A, 0x01, 0x02, // 39
0x00, 0x3B, 0x06, 0x04, // 40
0x00, 0x41, 0x06, 0x04, // 41
0x00, 0x47, 0x05, 0x04, // 42
0x00, 0x4C, 0x09, 0x06, // 43
0x00, 0x55, 0x04, 0x03, // 44
0x00, 0x59, 0x03, 0x03, // 45
0x00, 0x5C, 0x04, 0x03, // 46
0x00, 0x60, 0x05, 0x04, // 47
0x00, 0x65, 0x0A, 0x06, // 48
0x00, 0x6F, 0x08, 0x05, // 49
0x00, 0x77, 0x0A, 0x06, // 50
0x00, 0x81, 0x0A, 0x06, // 51
0x00, 0x8B, 0x0B, 0x07, // 52
0x00, 0x96, 0x0A, 0x06, // 53
0x00, 0xA0, 0x0A, 0x06, // 54
0x00, 0xAA, 0x09, 0x06, // 55
0x00, 0xB3, 0x0A, 0x06, // 56
0x00, 0xBD, 0x0A, 0x06, // 57
0x00, 0xC7, 0x04, 0x03, // 58
0x00, 0xCB, 0x04, 0x03, // 59
0x00, 0xCF, 0x0A, 0x06, // 60
0x00, 0xD9, 0x09, 0x06, // 61
0x00, 0xE2, 0x09, 0x06, // 62
0x00, 0xEB, 0x0B, 0x07, // 63
0x00, 0xF6, 0x14, 0x0B, // 64
0x01, 0x0A, 0x0E, 0x08, // 65
0x01, 0x18, 0x0C, 0x07, // 66
0x01, 0x24, 0x0C, 0x07, // 67
0x01, 0x30, 0x0B, 0x07, // 68
0x01, 0x3B, 0x0C, 0x07, // 69
0x01, 0x47, 0x09, 0x06, // 70
0x01, 0x50, 0x0D, 0x08, // 71
0x01, 0x5D, 0x0C, 0x07, // 72
0x01, 0x69, 0x04, 0x03, // 73
0x01, 0x6D, 0x08, 0x05, // 74
0x01, 0x75, 0x0E, 0x08, // 75
0x01, 0x83, 0x0C, 0x07, // 76
0x01, 0x8F, 0x10, 0x09, // 77
0x01, 0x9F, 0x0C, 0x07, // 78
0x01, 0xAB, 0x0E, 0x08, // 79
0x01, 0xB9, 0x0B, 0x07, // 80
0x01, 0xC4, 0x0E, 0x08, // 81
0x01, 0xD2, 0x0C, 0x07, // 82
0x01, 0xDE, 0x0C, 0x07, // 83
0x01, 0xEA, 0x0B, 0x07, // 84
0x01, 0xF5, 0x0C, 0x07, // 85
0x02, 0x01, 0x0D, 0x08, // 86
0x02, 0x0E, 0x11, 0x0A, // 87
0x02, 0x1F, 0x0E, 0x08, // 88
0x02, 0x2D, 0x0D, 0x08, // 89
0x02, 0x3A, 0x0C, 0x07, // 90
0x02, 0x46, 0x06, 0x04, // 91
0x02, 0x4C, 0x06, 0x04, // 92
0x02, 0x52, 0x04, 0x03, // 93
0x02, 0x56, 0x09, 0x06, // 94
0x02, 0x5F, 0x0C, 0x07, // 95
0x02, 0x6B, 0x03, 0x03, // 96
0x02, 0x6E, 0x0A, 0x06, // 97
0x02, 0x78, 0x0A, 0x06, // 98
0x02, 0x82, 0x0A, 0x06, // 99
0x02, 0x8C, 0x0A, 0x06, // 100
0x02, 0x96, 0x0A, 0x06, // 101
0x02, 0xA0, 0x05, 0x04, // 102
0x02, 0xA5, 0x0A, 0x06, // 103
0x02, 0xAF, 0x0A, 0x06, // 104
0x02, 0xB9, 0x04, 0x03, // 105
0x02, 0xBD, 0x04, 0x03, // 106
0x02, 0xC1, 0x08, 0x05, // 107
0x02, 0xC9, 0x04, 0x03, // 108
0x02, 0xCD, 0x10, 0x09, // 109
0x02, 0xDD, 0x0A, 0x06, // 110
0x02, 0xE7, 0x0A, 0x06, // 111
0x02, 0xF1, 0x0A, 0x06, // 112
0x02, 0xFB, 0x0A, 0x06, // 113
0x03, 0x05, 0x05, 0x04, // 114
0x03, 0x0A, 0x08, 0x05, // 115
0x03, 0x12, 0x06, 0x04, // 116
0x03, 0x18, 0x0A, 0x06, // 117
0x03, 0x22, 0x09, 0x06, // 118
0x03, 0x2B, 0x0E, 0x08, // 119
0x03, 0x39, 0x0A, 0x06, // 120
0x03, 0x43, 0x09, 0x06, // 121
0x03, 0x4C, 0x0A, 0x06, // 122
0x03, 0x56, 0x06, 0x04, // 123
0x03, 0x5C, 0x04, 0x03, // 124
0x03, 0x60, 0x05, 0x04, // 125
0x03, 0x65, 0x09, 0x06, // 126
0xFF, 0xFF, 0x00, 0x0A, // 127
0xFF, 0xFF, 0x00, 0x0A, // 128
0xFF, 0xFF, 0x00, 0x0A, // 129
0xFF, 0xFF, 0x00, 0x0A, // 130
0xFF, 0xFF, 0x00, 0x0A, // 131
0xFF, 0xFF, 0x00, 0x0A, // 132
0xFF, 0xFF, 0x00, 0x0A, // 133
0xFF, 0xFF, 0x00, 0x0A, // 134
0xFF, 0xFF, 0x00, 0x0A, // 135
0xFF, 0xFF, 0x00, 0x0A, // 136
0xFF, 0xFF, 0x00, 0x0A, // 137
0xFF, 0xFF, 0x00, 0x0A, // 138
0xFF, 0xFF, 0x00, 0x0A, // 139
0xFF, 0xFF, 0x00, 0x0A, // 140
0xFF, 0xFF, 0x00, 0x0A, // 141
0xFF, 0xFF, 0x00, 0x0A, // 142
0xFF, 0xFF, 0x00, 0x0A, // 143
0xFF, 0xFF, 0x00, 0x0A, // 144
0xFF, 0xFF, 0x00, 0x0A, // 145
0xFF, 0xFF, 0x00, 0x0A, // 146
0xFF, 0xFF, 0x00, 0x0A, // 147
0xFF, 0xFF, 0x00, 0x0A, // 148
0xFF, 0xFF, 0x00, 0x0A, // 149
0xFF, 0xFF, 0x00, 0x0A, // 150
0xFF, 0xFF, 0x00, 0x0A, // 151
0xFF, 0xFF, 0x00, 0x0A, // 152
0xFF, 0xFF, 0x00, 0x0A, // 153
0xFF, 0xFF, 0x00, 0x0A, // 154
0xFF, 0xFF, 0x00, 0x0A, // 155
0xFF, 0xFF, 0x00, 0x0A, // 156
0xFF, 0xFF, 0x00, 0x0A, // 157
0xFF, 0xFF, 0x00, 0x0A, // 158
0xFF, 0xFF, 0x00, 0x0A, // 159
0xFF, 0xFF, 0x00, 0x0A, // 160
0x03, 0x6E, 0x04, 0x03, // 161
0x03, 0x72, 0x0A, 0x06, // 162
0x03, 0x7C, 0x0C, 0x07, // 163
0x03, 0x88, 0x0A, 0x06, // 164
0x03, 0x92, 0x0A, 0x06, // 165
0x03, 0x9C, 0x04, 0x03, // 166
0x03, 0xA0, 0x0A, 0x06, // 167
0x03, 0xAA, 0x0C, 0x07, // 168
0x03, 0xB6, 0x0D, 0x08, // 169
0x03, 0xC3, 0x07, 0x05, // 170
0x03, 0xCA, 0x0A, 0x06, // 171
0x03, 0xD4, 0x09, 0x06, // 172
0x03, 0xDD, 0x03, 0x03, // 173
0x03, 0xE0, 0x0D, 0x08, // 174
0x03, 0xED, 0x0B, 0x07, // 175
0x03, 0xF8, 0x07, 0x05, // 176
0x03, 0xFF, 0x0A, 0x06, // 177
0x04, 0x09, 0x05, 0x04, // 178
0x04, 0x0E, 0x05, 0x04, // 179
0x04, 0x13, 0x05, 0x04, // 180
0x04, 0x18, 0x0A, 0x06, // 181
0x04, 0x22, 0x09, 0x06, // 182
0x04, 0x2B, 0x03, 0x03, // 183
0x04, 0x2E, 0x0B, 0x07, // 184
0x04, 0x39, 0x0B, 0x07, // 185
0x04, 0x44, 0x07, 0x05, // 186
0x04, 0x4B, 0x0A, 0x06, // 187
0x04, 0x55, 0x10, 0x09, // 188
0x04, 0x65, 0x10, 0x09, // 189
0x04, 0x75, 0x10, 0x09, // 190
0x04, 0x85, 0x0A, 0x06, // 191
0x04, 0x8F, 0x0C, 0x07, // 192
0x04, 0x9B, 0x0C, 0x07, // 193
0x04, 0xA7, 0x0C, 0x07, // 194
0x04, 0xB3, 0x0B, 0x07, // 195
0x04, 0xBE, 0x0C, 0x07, // 196
0x04, 0xCA, 0x0C, 0x07, // 197
0x04, 0xD6, 0x0C, 0x07, // 198
0x04, 0xE2, 0x0C, 0x07, // 199
0x04, 0xEE, 0x0C, 0x07, // 200
0x04, 0xFA, 0x0C, 0x07, // 201
0x05, 0x06, 0x0C, 0x07, // 202
0x05, 0x12, 0x0C, 0x07, // 203
0x05, 0x1E, 0x0C, 0x07, // 204
0x05, 0x2A, 0x0C, 0x07, // 205
0x05, 0x36, 0x0C, 0x07, // 206
0x05, 0x42, 0x0C, 0x07, // 207
0x05, 0x4E, 0x0B, 0x07, // 208
0x05, 0x59, 0x0C, 0x07, // 209
0x05, 0x65, 0x0B, 0x07, // 210
0x05, 0x70, 0x0C, 0x07, // 211
0x05, 0x7C, 0x0B, 0x07, // 212
0x05, 0x87, 0x0C, 0x07, // 213
0x05, 0x93, 0x0C, 0x07, // 214
0x05, 0x9F, 0x0C, 0x07, // 215
0x05, 0xAB, 0x0C, 0x07, // 216
0x05, 0xB7, 0x0E, 0x08, // 217
0x05, 0xC5, 0x0C, 0x07, // 218
0x05, 0xD1, 0x0C, 0x07, // 219
0x05, 0xDD, 0x0C, 0x07, // 220
0x05, 0xE9, 0x0C, 0x07, // 221
0x05, 0xF5, 0x0C, 0x07, // 222
0x06, 0x01, 0x0C, 0x07, // 223
0x06, 0x0D, 0x0C, 0x07, // 224
0x06, 0x19, 0x0C, 0x07, // 225
0x06, 0x25, 0x0C, 0x07, // 226
0x06, 0x31, 0x0B, 0x07, // 227
0x06, 0x3C, 0x0C, 0x07, // 228
0x06, 0x48, 0x0B, 0x07, // 229
0x06, 0x53, 0x0C, 0x07, // 230
0x06, 0x5F, 0x0C, 0x07, // 231
0x06, 0x6B, 0x0C, 0x07, // 232
0x06, 0x77, 0x0C, 0x07, // 233
0x06, 0x83, 0x0C, 0x07, // 234
0x06, 0x8F, 0x0C, 0x07, // 235
0x06, 0x9B, 0x0C, 0x07, // 236
0x06, 0xA7, 0x0C, 0x07, // 237
0x06, 0xB3, 0x0C, 0x07, // 238
0x06, 0xBF, 0x0C, 0x07, // 239
0x06, 0xCB, 0x0B, 0x07, // 240
0x06, 0xD6, 0x0C, 0x07, // 241
0x06, 0xE2, 0x0B, 0x07, // 242
0x06, 0xED, 0x0C, 0x07, // 243
0x06, 0xF9, 0x0B, 0x07, // 244
0x07, 0x04, 0x0C, 0x07, // 245
0x07, 0x10, 0x0C, 0x07, // 246
0x07, 0x1C, 0x0C, 0x07, // 247
0x07, 0x28, 0x0C, 0x07, // 248
0x07, 0x34, 0x0E, 0x08, // 249
0x07, 0x42, 0x0C, 0x07, // 250
0x07, 0x4E, 0x0C, 0x07, // 251
0x07, 0x5A, 0x0C, 0x07, // 252
0x07, 0x66, 0x0C, 0x07, // 253
0x07, 0x72, 0x0C, 0x07, // 254
0x07, 0x7E, 0x0C, 0x07, // 255
// Font Data:
0x00, 0x00, 0xF8, 0x02, // 33
0x38, 0x00, 0x00, 0x00, 0x38, // 34
0xA0, 0x03, 0xE0, 0x00, 0xB8, 0x03, 0xE0, 0x00, 0xB8, // 35
0x30, 0x01, 0x28, 0x02, 0xF8, 0x07, 0x48, 0x02, 0x90, 0x01, // 36
0x00, 0x00, 0x30, 0x00, 0x48, 0x00, 0x30, 0x03, 0xC0, 0x00, 0xB0, 0x01, 0x48, 0x02, 0x80, 0x01, // 37
0x80, 0x01, 0x50, 0x02, 0x68, 0x02, 0xA8, 0x02, 0x18, 0x01, 0x80, 0x03, 0x80, 0x02, // 38
0x38, // 39
0xE0, 0x03, 0x10, 0x04, 0x08, 0x08, // 40
0x08, 0x08, 0x10, 0x04, 0xE0, 0x03, // 41
0x28, 0x00, 0x18, 0x00, 0x28, // 42
0x40, 0x00, 0x40, 0x00, 0xF0, 0x01, 0x40, 0x00, 0x40, // 43
0x00, 0x00, 0x00, 0x06, // 44
0x80, 0x00, 0x80, // 45
0x00, 0x00, 0x00, 0x02, // 46
0x00, 0x03, 0xE0, 0x00, 0x18, // 47
0xF0, 0x01, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0xF0, 0x01, // 48
0x00, 0x00, 0x20, 0x00, 0x10, 0x00, 0xF8, 0x03, // 49
0x10, 0x02, 0x08, 0x03, 0x88, 0x02, 0x48, 0x02, 0x30, 0x02, // 50
0x10, 0x01, 0x08, 0x02, 0x48, 0x02, 0x48, 0x02, 0xB0, 0x01, // 51
0xC0, 0x00, 0xA0, 0x00, 0x90, 0x00, 0x88, 0x00, 0xF8, 0x03, 0x80, // 52
0x60, 0x01, 0x38, 0x02, 0x28, 0x02, 0x28, 0x02, 0xC8, 0x01, // 53
0xF0, 0x01, 0x28, 0x02, 0x28, 0x02, 0x28, 0x02, 0xD0, 0x01, // 54
0x08, 0x00, 0x08, 0x03, 0xC8, 0x00, 0x38, 0x00, 0x08, // 55
0xB0, 0x01, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, 0xB0, 0x01, // 56
0x70, 0x01, 0x88, 0x02, 0x88, 0x02, 0x88, 0x02, 0xF0, 0x01, // 57
0x00, 0x00, 0x20, 0x02, // 58
0x00, 0x00, 0x20, 0x06, // 59
0x00, 0x00, 0x40, 0x00, 0xA0, 0x00, 0xA0, 0x00, 0x10, 0x01, // 60
0xA0, 0x00, 0xA0, 0x00, 0xA0, 0x00, 0xA0, 0x00, 0xA0, // 61
0x00, 0x00, 0x10, 0x01, 0xA0, 0x00, 0xA0, 0x00, 0x40, // 62
0x10, 0x00, 0x08, 0x00, 0x08, 0x00, 0xC8, 0x02, 0x48, 0x00, 0x30, // 63
0x00, 0x00, 0xC0, 0x03, 0x30, 0x04, 0xD0, 0x09, 0x28, 0x0A, 0x28, 0x0A, 0xC8, 0x0B, 0x68, 0x0A, 0x10, 0x05, 0xE0, 0x04, // 64
0x00, 0x02, 0xC0, 0x01, 0xB0, 0x00, 0x88, 0x00, 0xB0, 0x00, 0xC0, 0x01, 0x00, 0x02, // 65
0x00, 0x00, 0xF8, 0x03, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, 0xF0, 0x01, // 66
0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x10, 0x01, // 67
0x00, 0x00, 0xF8, 0x03, 0x08, 0x02, 0x08, 0x02, 0x10, 0x01, 0xE0, // 68
0x00, 0x00, 0xF8, 0x03, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, // 69
0x00, 0x00, 0xF8, 0x03, 0x48, 0x00, 0x48, 0x00, 0x08, // 70
0x00, 0x00, 0xE0, 0x00, 0x10, 0x01, 0x08, 0x02, 0x48, 0x02, 0x50, 0x01, 0xC0, // 71
0x00, 0x00, 0xF8, 0x03, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0xF8, 0x03, // 72
0x00, 0x00, 0xF8, 0x03, // 73
0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0xF8, 0x01, // 74
0x00, 0x00, 0xF8, 0x03, 0x80, 0x00, 0x60, 0x00, 0x90, 0x00, 0x08, 0x01, 0x00, 0x02, // 75
0x00, 0x00, 0xF8, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, // 76
0x00, 0x00, 0xF8, 0x03, 0x30, 0x00, 0xC0, 0x01, 0x00, 0x02, 0xC0, 0x01, 0x30, 0x00, 0xF8, 0x03, // 77
0x00, 0x00, 0xF8, 0x03, 0x30, 0x00, 0x40, 0x00, 0x80, 0x01, 0xF8, 0x03, // 78
0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0xF0, 0x01, // 79
0x00, 0x00, 0xF8, 0x03, 0x48, 0x00, 0x48, 0x00, 0x48, 0x00, 0x30, // 80
0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x08, 0x02, 0x08, 0x03, 0x08, 0x03, 0xF0, 0x02, // 81
0x00, 0x00, 0xF8, 0x03, 0x48, 0x00, 0x48, 0x00, 0xC8, 0x00, 0x30, 0x03, // 82
0x00, 0x00, 0x30, 0x01, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, 0x90, 0x01, // 83
0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0xF8, 0x03, 0x08, 0x00, 0x08, // 84
0x00, 0x00, 0xF8, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0xF8, 0x01, // 85
0x08, 0x00, 0x70, 0x00, 0x80, 0x01, 0x00, 0x02, 0x80, 0x01, 0x70, 0x00, 0x08, // 86
0x18, 0x00, 0xE0, 0x01, 0x00, 0x02, 0xF0, 0x01, 0x08, 0x00, 0xF0, 0x01, 0x00, 0x02, 0xE0, 0x01, 0x18, // 87
0x00, 0x02, 0x08, 0x01, 0x90, 0x00, 0x60, 0x00, 0x90, 0x00, 0x08, 0x01, 0x00, 0x02, // 88
0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0xC0, 0x03, 0x20, 0x00, 0x10, 0x00, 0x08, // 89
0x08, 0x03, 0x88, 0x02, 0xC8, 0x02, 0x68, 0x02, 0x38, 0x02, 0x18, 0x02, // 90
0x00, 0x00, 0xF8, 0x0F, 0x08, 0x08, // 91
0x18, 0x00, 0xE0, 0x00, 0x00, 0x03, // 92
0x08, 0x08, 0xF8, 0x0F, // 93
0x40, 0x00, 0x30, 0x00, 0x08, 0x00, 0x30, 0x00, 0x40, // 94
0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, // 95
0x08, 0x00, 0x10, // 96
0x00, 0x00, 0x00, 0x03, 0xA0, 0x02, 0xA0, 0x02, 0xE0, 0x03, // 97
0x00, 0x00, 0xF8, 0x03, 0x20, 0x02, 0x20, 0x02, 0xC0, 0x01, // 98
0x00, 0x00, 0xC0, 0x01, 0x20, 0x02, 0x20, 0x02, 0x40, 0x01, // 99
0x00, 0x00, 0xC0, 0x01, 0x20, 0x02, 0x20, 0x02, 0xF8, 0x03, // 100
0x00, 0x00, 0xC0, 0x01, 0xA0, 0x02, 0xA0, 0x02, 0xC0, 0x02, // 101
0x20, 0x00, 0xF0, 0x03, 0x28, // 102
0x00, 0x00, 0xC0, 0x05, 0x20, 0x0A, 0x20, 0x0A, 0xE0, 0x07, // 103
0x00, 0x00, 0xF8, 0x03, 0x20, 0x00, 0x20, 0x00, 0xC0, 0x03, // 104
0x00, 0x00, 0xE8, 0x03, // 105
0x00, 0x08, 0xE8, 0x07, // 106
0xF8, 0x03, 0x80, 0x00, 0xC0, 0x01, 0x20, 0x02, // 107
0x00, 0x00, 0xF8, 0x03, // 108
0x00, 0x00, 0xE0, 0x03, 0x20, 0x00, 0x20, 0x00, 0xE0, 0x03, 0x20, 0x00, 0x20, 0x00, 0xC0, 0x03, // 109
0x00, 0x00, 0xE0, 0x03, 0x20, 0x00, 0x20, 0x00, 0xC0, 0x03, // 110
0x00, 0x00, 0xC0, 0x01, 0x20, 0x02, 0x20, 0x02, 0xC0, 0x01, // 111
0x00, 0x00, 0xE0, 0x0F, 0x20, 0x02, 0x20, 0x02, 0xC0, 0x01, // 112
0x00, 0x00, 0xC0, 0x01, 0x20, 0x02, 0x20, 0x02, 0xE0, 0x0F, // 113
0x00, 0x00, 0xE0, 0x03, 0x20, // 114
0x40, 0x02, 0xA0, 0x02, 0xA0, 0x02, 0x20, 0x01, // 115
0x20, 0x00, 0xF8, 0x03, 0x20, 0x02, // 116
0x00, 0x00, 0xE0, 0x01, 0x00, 0x02, 0x00, 0x02, 0xE0, 0x03, // 117
0x20, 0x00, 0xC0, 0x01, 0x00, 0x02, 0xC0, 0x01, 0x20, // 118
0xE0, 0x01, 0x00, 0x02, 0xC0, 0x01, 0x20, 0x00, 0xC0, 0x01, 0x00, 0x02, 0xE0, 0x01, // 119
0x20, 0x02, 0x40, 0x01, 0x80, 0x00, 0x40, 0x01, 0x20, 0x02, // 120
0x20, 0x00, 0xC0, 0x09, 0x00, 0x06, 0xC0, 0x01, 0x20, // 121
0x20, 0x02, 0x20, 0x03, 0xA0, 0x02, 0x60, 0x02, 0x20, 0x02, // 122
0x80, 0x00, 0x78, 0x0F, 0x08, 0x08, // 123
0x00, 0x00, 0xF8, 0x0F, // 124
0x08, 0x08, 0x78, 0x0F, 0x80, // 125
0xC0, 0x00, 0x40, 0x00, 0xC0, 0x00, 0x80, 0x00, 0xC0, // 126
0x00, 0x00, 0xA0, 0x0F, // 161
0x00, 0x00, 0xC0, 0x01, 0xA0, 0x0F, 0x78, 0x02, 0x40, 0x01, // 162
0x40, 0x02, 0x70, 0x03, 0xC8, 0x02, 0x48, 0x02, 0x08, 0x02, 0x10, 0x02, // 163
0x00, 0x00, 0xE0, 0x01, 0x20, 0x01, 0x20, 0x01, 0xE0, 0x01, // 164
0x48, 0x01, 0x70, 0x01, 0xC0, 0x03, 0x70, 0x01, 0x48, 0x01, // 165
0x00, 0x00, 0x38, 0x0F, // 166
0xD0, 0x04, 0x28, 0x09, 0x48, 0x09, 0x48, 0x0A, 0x90, 0x05, // 167
0x00, 0x00, 0xE0, 0x03, 0xA8, 0x02, 0xA0, 0x02, 0xA8, 0x02, 0x20, 0x02, // 168
0xE0, 0x00, 0x10, 0x01, 0x48, 0x02, 0xA8, 0x02, 0xA8, 0x02, 0x10, 0x01, 0xE0, // 169
0x68, 0x00, 0x68, 0x00, 0x68, 0x00, 0x78, // 170
0x00, 0x00, 0x80, 0x01, 0x40, 0x02, 0x80, 0x01, 0x40, 0x02, // 171
0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0xE0, // 172
0x80, 0x00, 0x80, // 173
0xE0, 0x00, 0x10, 0x01, 0xE8, 0x02, 0x68, 0x02, 0xC8, 0x02, 0x10, 0x01, 0xE0, // 174
0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, // 175
0x00, 0x00, 0x38, 0x00, 0x28, 0x00, 0x38, // 176
0x40, 0x02, 0x40, 0x02, 0xF0, 0x03, 0x40, 0x02, 0x40, 0x02, // 177
0x48, 0x00, 0x68, 0x00, 0x58, // 178
0x48, 0x00, 0x58, 0x00, 0x68, // 179
0x00, 0x00, 0x10, 0x00, 0x08, // 180
0x00, 0x00, 0xE0, 0x0F, 0x00, 0x02, 0x00, 0x02, 0xE0, 0x03, // 181
0x70, 0x00, 0xF8, 0x0F, 0x08, 0x00, 0xF8, 0x0F, 0x08, // 182
0x00, 0x00, 0x40, // 183
0x00, 0x00, 0xC0, 0x01, 0xA8, 0x02, 0xA0, 0x02, 0xA8, 0x02, 0xC0, // 184
0x00, 0x00, 0xF0, 0x03, 0x40, 0x00, 0x80, 0x00, 0xF8, 0x03, 0x08, // 185
0x30, 0x00, 0x48, 0x00, 0x48, 0x00, 0x30, // 186
0x00, 0x00, 0x40, 0x02, 0x80, 0x01, 0x40, 0x02, 0x80, 0x01, // 187
0x00, 0x00, 0x10, 0x02, 0x78, 0x01, 0xC0, 0x00, 0x20, 0x01, 0x90, 0x01, 0xC8, 0x03, 0x00, 0x01, // 188
0x00, 0x00, 0x10, 0x02, 0x78, 0x01, 0x80, 0x00, 0x60, 0x00, 0x50, 0x02, 0x48, 0x03, 0xC0, 0x02, // 189
0x48, 0x00, 0x58, 0x00, 0x68, 0x03, 0x80, 0x00, 0x60, 0x01, 0x90, 0x01, 0xC8, 0x03, 0x00, 0x01, // 190
0x00, 0x00, 0x00, 0x06, 0x00, 0x09, 0xA0, 0x09, 0x00, 0x04, // 191
0x00, 0x00, 0xF0, 0x03, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0xF0, 0x03, // 192
0x00, 0x00, 0xF8, 0x03, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, 0x88, 0x01, // 193
0x00, 0x00, 0xF8, 0x03, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, 0xB0, 0x01, // 194
0x00, 0x00, 0xF8, 0x03, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x18, // 195
0x00, 0x00, 0x00, 0x02, 0xFC, 0x03, 0x04, 0x02, 0xFC, 0x03, 0x00, 0x02, // 196
0x00, 0x00, 0xF8, 0x03, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, 0x08, 0x02, // 197
0x00, 0x00, 0xB8, 0x03, 0x40, 0x00, 0xF8, 0x03, 0x40, 0x00, 0xB8, 0x03, // 198
0x00, 0x00, 0x08, 0x02, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, 0xB0, 0x01, // 199
0x00, 0x00, 0xF8, 0x03, 0x80, 0x00, 0x40, 0x00, 0x20, 0x00, 0xF8, 0x03, // 200
0x00, 0x00, 0xE0, 0x03, 0x08, 0x01, 0x90, 0x00, 0x48, 0x00, 0xE0, 0x03, // 201
0x00, 0x00, 0xF8, 0x03, 0x40, 0x00, 0xA0, 0x00, 0x10, 0x01, 0x08, 0x02, // 202
0x00, 0x00, 0x00, 0x02, 0xF0, 0x01, 0x08, 0x00, 0x08, 0x00, 0xF8, 0x03, // 203
0x00, 0x00, 0xF8, 0x03, 0x10, 0x00, 0x60, 0x00, 0x10, 0x00, 0xF8, 0x03, // 204
0x00, 0x00, 0xF8, 0x03, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0xF8, 0x03, // 205
0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0xF0, 0x01, // 206
0x00, 0x00, 0xF8, 0x03, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0xF8, 0x03, // 207
0x00, 0x00, 0xF8, 0x03, 0x48, 0x00, 0x48, 0x00, 0x48, 0x00, 0x30, // 208
0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x10, 0x01, // 209
0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0xF8, 0x03, 0x08, 0x00, 0x08, // 210
0x00, 0x00, 0x38, 0x00, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0xF8, 0x01, // 211
0x00, 0x00, 0x70, 0x00, 0x88, 0x00, 0xF8, 0x03, 0x88, 0x00, 0x70, // 212
0x00, 0x00, 0x18, 0x03, 0xA0, 0x00, 0x40, 0x00, 0xA0, 0x00, 0x18, 0x03, // 213
0x00, 0x00, 0xF8, 0x03, 0x00, 0x02, 0x00, 0x02, 0xF8, 0x03, 0x00, 0x02, // 214
0x00, 0x00, 0x38, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0xF8, 0x03, // 215
0x00, 0x00, 0xF8, 0x03, 0x00, 0x02, 0xF8, 0x03, 0x00, 0x02, 0xF8, 0x03, // 216
0x00, 0x00, 0xF8, 0x03, 0x00, 0x02, 0xF8, 0x03, 0x00, 0x02, 0xF8, 0x03, 0x00, 0x06, // 217
0x00, 0x00, 0x08, 0x00, 0xF8, 0x03, 0x40, 0x02, 0x40, 0x02, 0x80, 0x01, // 218
0x00, 0x00, 0xF8, 0x03, 0x40, 0x02, 0x40, 0x02, 0x80, 0x01, 0xF8, 0x03, // 219
0x00, 0x00, 0xF8, 0x03, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x80, 0x01, // 220
0x00, 0x00, 0x10, 0x01, 0x08, 0x02, 0x48, 0x02, 0x48, 0x02, 0xF0, 0x01, // 221
0x00, 0x00, 0xF8, 0x03, 0x40, 0x00, 0xF0, 0x01, 0x08, 0x02, 0xF0, 0x01, // 222
0x00, 0x00, 0x30, 0x02, 0x48, 0x01, 0xC8, 0x00, 0x48, 0x00, 0xF8, 0x03, // 223
0x00, 0x00, 0x00, 0x01, 0xA0, 0x02, 0xA0, 0x02, 0xA0, 0x02, 0xC0, 0x03, // 224
0x00, 0x00, 0xE0, 0x01, 0x50, 0x02, 0x50, 0x02, 0x48, 0x02, 0x88, 0x01, // 225
0x00, 0x00, 0xE0, 0x03, 0xA0, 0x02, 0xA0, 0x02, 0xA0, 0x02, 0x40, 0x01, // 226
0x00, 0x00, 0xE0, 0x03, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x60, // 227
0x00, 0x00, 0x00, 0x02, 0xC0, 0x03, 0x20, 0x02, 0xE0, 0x03, 0x00, 0x02, // 228
0x00, 0x00, 0xC0, 0x01, 0xA0, 0x02, 0xA0, 0x02, 0xA0, 0x02, 0xC0, // 229
0x00, 0x00, 0x60, 0x03, 0x80, 0x00, 0xE0, 0x03, 0x80, 0x00, 0x60, 0x03, // 230
0x00, 0x00, 0x20, 0x02, 0xA0, 0x02, 0xA0, 0x02, 0xA0, 0x02, 0x40, 0x01, // 231
0x00, 0x00, 0xE0, 0x03, 0x00, 0x01, 0x80, 0x00, 0x40, 0x00, 0xE0, 0x03, // 232
0x00, 0x00, 0xE0, 0x03, 0x00, 0x01, 0x98, 0x00, 0x40, 0x00, 0xE0, 0x03, // 233
0x00, 0x00, 0xE0, 0x03, 0x80, 0x00, 0x80, 0x00, 0x40, 0x01, 0x20, 0x02, // 234
0x00, 0x00, 0x00, 0x02, 0xC0, 0x01, 0x20, 0x00, 0x20, 0x00, 0xE0, 0x03, // 235
0x00, 0x00, 0xE0, 0x03, 0x40, 0x00, 0x80, 0x00, 0x40, 0x00, 0xE0, 0x03, // 236
0x00, 0x00, 0xE0, 0x03, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0xE0, 0x03, // 237
0x00, 0x00, 0xC0, 0x01, 0x20, 0x02, 0x20, 0x02, 0x20, 0x02, 0xC0, 0x01, // 238
0x00, 0x00, 0xE0, 0x03, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0xE0, 0x03, // 239
0x00, 0x00, 0xE0, 0x03, 0xA0, 0x00, 0xA0, 0x00, 0xA0, 0x00, 0x40, // 240
0x00, 0x00, 0xC0, 0x01, 0x20, 0x02, 0x20, 0x02, 0x20, 0x02, 0x40, 0x02, // 241
0x00, 0x00, 0x20, 0x00, 0x20, 0x00, 0xE0, 0x03, 0x20, 0x00, 0x20, // 242
0x00, 0x00, 0x60, 0x00, 0x80, 0x02, 0x80, 0x02, 0x80, 0x02, 0xE0, 0x01, // 243
0x00, 0x00, 0xC0, 0x00, 0x20, 0x01, 0xE0, 0x03, 0x20, 0x01, 0xC0, // 244
0x00, 0x00, 0x20, 0x02, 0x40, 0x01, 0x80, 0x00, 0x40, 0x01, 0x20, 0x02, // 245
0x00, 0x00, 0xE0, 0x03, 0x00, 0x02, 0x00, 0x02, 0xE0, 0x03, 0x00, 0x02, // 246
0x00, 0x00, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0xE0, 0x03, // 247
0x00, 0x00, 0xE0, 0x03, 0x00, 0x02, 0xE0, 0x03, 0x00, 0x02, 0xE0, 0x03, // 248
0x00, 0x00, 0xE0, 0x03, 0x00, 0x02, 0xE0, 0x03, 0x00, 0x02, 0xE0, 0x03, 0x00, 0x06, // 249
0x00, 0x00, 0x20, 0x00, 0xE0, 0x03, 0x80, 0x02, 0x80, 0x02, 0x00, 0x01, // 250
0x00, 0x00, 0xE0, 0x03, 0x80, 0x02, 0x80, 0x02, 0x00, 0x01, 0xE0, 0x03, // 251
0x00, 0x00, 0xE0, 0x03, 0x80, 0x02, 0x80, 0x02, 0x80, 0x02, 0x00, 0x01, // 252
0x00, 0x00, 0x40, 0x01, 0x20, 0x02, 0xA0, 0x02, 0xA0, 0x02, 0xC0, 0x01, // 253
0x00, 0x00, 0xE0, 0x03, 0x80, 0x00, 0xC0, 0x01, 0x20, 0x02, 0xC0, 0x01, // 254
0x00, 0x00, 0x40, 0x02, 0xA0, 0x01, 0xA0, 0x00, 0xA0, 0x00, 0xE0, 0x03, // 255
};
+11
View File
@@ -0,0 +1,11 @@
#ifndef OLEDDISPLAYFONTSRU_h
#define OLEDDISPLAYFONTSRU_h
#ifdef ARDUINO
#include <Arduino.h>
#elif __MBED__
#define PROGMEM
#endif
extern const uint8_t ArialMT_Plain_10_RU[] PROGMEM;
#endif
+4
View File
@@ -1,9 +1,13 @@
#pragma once
#include "Observer.h"
#define ANYKEY 0xFF
#define MATRIXKEY 0xFE
typedef struct _InputEvent {
const char* source;
char inputEvent;
char kbchar;
} InputEvent;
class InputBroker :
public Observable<const InputEvent *>
+2 -2
View File
@@ -34,7 +34,7 @@ void RotaryEncoderInterruptBase::init(
int32_t RotaryEncoderInterruptBase::runOnce()
{
InputEvent e;
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE;
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
e.source = this->_originName;
if (this->action == ROTARY_ACTION_PRESSED) {
@@ -48,7 +48,7 @@ int32_t RotaryEncoderInterruptBase::runOnce()
e.inputEvent = this->_eventCcw;
}
if (e.inputEvent != ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE) {
if (e.inputEvent != ModuleConfig_CannedMessageConfig_InputEventChar_NONE) {
this->notifyObservers(&e);
}
+3 -3
View File
@@ -33,8 +33,8 @@ class RotaryEncoderInterruptBase : public Observable<const InputEvent *>, privat
private:
uint8_t _pinA = 0;
uint8_t _pinB = 0;
char _eventCw = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE;
char _eventCcw = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE;
char _eventPressed = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE;
char _eventCw = ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
char _eventCcw = ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
char _eventPressed = ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
const char *_originName;
};
+3 -3
View File
@@ -16,8 +16,8 @@ class UpDownInterruptBase : public Observable<const InputEvent *>
private:
uint8_t _pinDown = 0;
uint8_t _pinUp = 0;
char _eventDown = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE;
char _eventUp = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE;
char _eventPressed = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE;
char _eventDown = ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
char _eventUp = ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
char _eventPressed = ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
const char *_originName;
};
+3 -3
View File
@@ -17,9 +17,9 @@ void UpDownInterruptImpl1::init()
uint8_t pinDown = moduleConfig.canned_message.inputbroker_pin_b;
uint8_t pinPress = moduleConfig.canned_message.inputbroker_pin_press;
char eventDown = static_cast<char>(ModuleConfig_CannedMessageConfig_InputEventChar_KEY_DOWN);
char eventUp = static_cast<char>(ModuleConfig_CannedMessageConfig_InputEventChar_KEY_UP);
char eventPressed = static_cast<char>(ModuleConfig_CannedMessageConfig_InputEventChar_KEY_SELECT);
char eventDown = static_cast<char>(ModuleConfig_CannedMessageConfig_InputEventChar_DOWN);
char eventUp = static_cast<char>(ModuleConfig_CannedMessageConfig_InputEventChar_UP);
char eventPressed = static_cast<char>(ModuleConfig_CannedMessageConfig_InputEventChar_SELECT);
UpDownInterruptBase::init(pinDown, pinUp, pinPress, eventDown, eventUp, eventPressed, UpDownInterruptImpl1::handleIntDown,
UpDownInterruptImpl1::handleIntUp, UpDownInterruptImpl1::handleIntPressed);
-1
View File
@@ -16,6 +16,5 @@ void CardKbI2cImpl::init()
return;
}
DEBUG_MSG("registerSource\n");
inputBroker->registerSource(this);
}
-20
View File
@@ -1,20 +0,0 @@
#include "facesKbI2cImpl.h"
#include "InputBroker.h"
FacesKbI2cImpl *facesKbI2cImpl;
FacesKbI2cImpl::FacesKbI2cImpl() :
KbI2cBase("facesKB")
{
}
void FacesKbI2cImpl::init()
{
if (faceskb_found != FACESKB_ADDR)
{
// Input device is not detected.
return;
}
inputBroker->registerSource(this);
}
-20
View File
@@ -1,20 +0,0 @@
#pragma once
#include "kbI2cBase.h"
#include "main.h"
/**
* @brief The idea behind this class to have static methods for the event handlers.
* Check attachInterrupt() at RotaryEncoderInteruptBase.cpp
* Technically you can have as many rotary encoders hardver attached
* to your device as you wish, but you always need to have separate event
* handlers, thus you need to have a RotaryEncoderInterrupt implementation.
*/
class FacesKbI2cImpl :
public KbI2cBase
{
public:
FacesKbI2cImpl();
void init();
};
extern FacesKbI2cImpl *facesKbI2cImpl;
+99 -33
View File
@@ -2,48 +2,114 @@
#include "configuration.h"
#include <Wire.h>
extern uint8_t cardkb_found;
extern uint8_t kb_model;
KbI2cBase::KbI2cBase(const char *name) : concurrency::OSThread(name)
{
this->_originName = name;
}
uint8_t read_from_14004(uint8_t reg, uint8_t *data, uint8_t length)
{
uint8_t readflag = 0;
Wire.beginTransmission(CARDKB_ADDR);
Wire.write(reg);
Wire.endTransmission(); // stop transmitting
delay(20);
Wire.requestFrom(CARDKB_ADDR, length);
int i = 0;
while ( Wire.available() ) // slave may send less than requested
{
data[i++] = Wire.read(); // receive a byte as a proper uint8_t
readflag = 1;
}
return readflag;
}
void write_to_14004(uint8_t reg, uint8_t data)
{
Wire.beginTransmission(CARDKB_ADDR);
Wire.write(reg);
Wire.write(data);
Wire.endTransmission(); // stop transmitting
}
int32_t KbI2cBase::runOnce()
{
InputEvent e;
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE;
e.source = this->_originName;
Wire.requestFrom(CARDKB_ADDR, 1);
while (Wire.available()) {
char c = Wire.read();
switch (c) {
case 0x1b: // ESC
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_CANCEL;
break;
case 0x08: // Back
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_BACK;
break;
case 0xb5: // Up
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_UP;
break;
case 0xb6: // Down
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_DOWN;
break;
case 0xb4: // Left
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_LEFT;
break;
case 0xb7: // Right
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_RIGHT;
break;
case 0x0d: // Enter
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_SELECT;
break;
}
if (cardkb_found != CARDKB_ADDR){
// Input device is not detected.
return INT32_MAX;
}
if (e.inputEvent != ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE) {
this->notifyObservers(&e);
if (kb_model == 0x02) {
// RAK14004
uint8_t rDataBuf[8] = {0};
uint8_t PrintDataBuf = 0;
if (read_from_14004(0x01, rDataBuf, 0x04) == 1) {
for (uint8_t aCount = 0; aCount < 0x04; aCount++) {
for (uint8_t bCount = 0; bCount < 0x04; bCount++ ) {
if (((rDataBuf[aCount] >> bCount) & 0x01) == 0x01) {
PrintDataBuf = aCount * 0x04 + bCount + 1;
}
}
}
}
if (PrintDataBuf != 0) {
DEBUG_MSG("RAK14004 key 0x%x pressed\n", PrintDataBuf);
InputEvent e;
e.inputEvent = MATRIXKEY;
e.source = this->_originName;
e.kbchar = PrintDataBuf;
this->notifyObservers(&e);
}
} else {
// m5 cardkb
Wire.requestFrom(CARDKB_ADDR, 1);
while (Wire.available()) {
char c = Wire.read();
InputEvent e;
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
e.source = this->_originName;
switch (c) {
case 0x1b: // ESC
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_CANCEL;
break;
case 0x08: // Back
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_BACK;
e.kbchar = c;
break;
case 0xb5: // Up
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_UP;
break;
case 0xb6: // Down
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_DOWN;
break;
case 0xb4: // Left
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_LEFT;
e.kbchar = c;
break;
case 0xb7: // Right
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT;
e.kbchar = c;
break;
case 0x0d: // Enter
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_SELECT;
break;
case 0x00: //nopress
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
break;
default: // all other keys
e.inputEvent = ANYKEY;
e.kbchar = c;
break;
}
if (e.inputEvent != ModuleConfig_CannedMessageConfig_InputEventChar_NONE) {
this->notifyObservers(&e);
}
}
}
return 500;
}
+47 -38
View File
@@ -17,9 +17,9 @@
#include "SPILock.h"
#include "concurrency/OSThread.h"
#include "concurrency/Periodic.h"
#include "debug/axpDebug.h"
#include "debug/einkScan.h"
#include "debug/i2cScan.h"
#include "detect/axpDebug.h"
#include "detect/einkScan.h"
#include "detect/i2cScan.h"
#include "graphics/Screen.h"
#include "main.h"
#include "modules/Modules.h"
@@ -31,18 +31,12 @@
#include "mesh/http/WiFiAPClient.h"
#ifndef NO_ESP32
#ifdef ARCH_ESP32
#include "mesh/http/WebServer.h"
#ifdef USE_NEW_ESP32_BLUETOOTH
#include "esp32/ESP32Bluetooth.h"
#else
#include "nimble/BluetoothUtil.h"
#include "nimble/NimbleBluetooth.h"
#endif
#endif
#if defined(HAS_WIFI) || defined(PORTDUINO)
#if HAS_WIFI || defined(ARCH_PORTDUINO)
#include "mesh/wifi/WiFiServerAPI.h"
#include "mqtt/MQTT.h"
#endif
@@ -51,8 +45,13 @@
#include "RF95Interface.h"
#include "SX1262Interface.h"
#include "SX1268Interface.h"
#if !HAS_RADIO && defined(ARCH_PORTDUINO)
#include "platform/portduino/SimRadio.h"
#endif
#if HAS_BUTTON
#include "ButtonThread.h"
#endif
#include "PowerFSMThread.h"
using namespace concurrency;
@@ -78,9 +77,6 @@ uint8_t cardkb_found;
// 0x02 for RAK14004 and 0x00 for cardkb
uint8_t kb_model;
// The I2C address of the Faces Keyboard (if found)
uint8_t faceskb_found;
// The I2C address of the RTC Module (if found)
uint8_t rtc_found;
@@ -88,7 +84,10 @@ bool eink_found = true;
uint32_t serialSinceMsec;
bool axp192_found;
bool pmu_found;
// Array map of sensor types (as array index) and i2c address as value we'll find in the i2c scan
uint8_t nodeTelemetrySensorsMap[TelemetrySensorType_LPS22+1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
Router *router = NULL; // Users of router don't care what sort of subclass implements that API
@@ -98,9 +97,15 @@ const char *getDeviceName()
getMacAddr(dmac);
// Meshtastic_ab3c
// Meshtastic_ab3c or Shortname_abcd
static char name[20];
sprintf(name, "Meshtastic_%02x%02x", dmac[4], dmac[5]);
sprintf(name, "%02x%02x", dmac[4], dmac[5]);
// if the shortname exists and is NOT the new default of ab3c, use it for BLE name.
if ((owner.short_name != NULL) && (strcmp(owner.short_name, name) != 0)) {
sprintf(name, "%s_%02x%02x", owner.short_name, dmac[4], dmac[5]);
} else {
sprintf(name, "Meshtastic_%02x%02x", dmac[4], dmac[5]);
}
return name;
}
@@ -117,11 +122,15 @@ static int32_t ledBlinker()
uint32_t timeLastPowered = 0;
#if HAS_BUTTON
bool ButtonThread::shutdown_on_long_stop = false;
#endif
static Periodic *ledPeriodic;
static OSThread *powerFSMthread, *buttonThread;
#if HAS_BUTTON
uint32_t ButtonThread::longPressTime = 0;
#endif
RadioInterface *rIf = NULL;
@@ -148,9 +157,7 @@ void setup()
#endif
#ifdef DEBUG_PORT
if (!config.device.serial_disabled) {
consoleInit(); // Set serial baud rate and init our mesh console
}
#endif
serialSinceMsec = millis();
@@ -178,7 +185,7 @@ void setup()
bool forceSoftAP = 0;
#ifdef BUTTON_PIN
#ifndef NO_ESP32
#ifdef ARCH_ESP32
// If the button is connected to GPIO 12, don't enable the ability to use
// meshtasticAdmin on the device.
@@ -209,7 +216,7 @@ void setup()
#ifdef I2C_SDA
Wire.begin(I2C_SDA, I2C_SCL);
#elif !defined(NO_WIRE)
#elif HAS_WIRE
Wire.begin();
#endif
@@ -227,8 +234,10 @@ void setup()
// scanEInkDevice();
#endif
#if HAS_BUTTON
// Buttons & LED
buttonThread = new ButtonThread();
#endif
#ifdef LED_PIN
pinMode(LED_PIN, OUTPUT);
@@ -238,7 +247,7 @@ void setup()
// Hello
DEBUG_MSG("Meshtastic hwvendor=%d, swver=%s\n", HW_VENDOR, optstr(APP_VERSION));
#ifndef NO_ESP32
#ifdef ARCH_ESP32
// Don't init display if we don't have one or we are waking headless due to a timer event
if (wakeCause == ESP_SLEEP_WAKEUP_TIMER)
screen_found = 0; // forget we even have the hardware
@@ -246,7 +255,7 @@ void setup()
esp32Setup();
#endif
#ifdef NRF52_SERIES
#ifdef ARCH_NRF52
nrf52Setup();
#endif
playStartMelody();
@@ -262,7 +271,7 @@ void setup()
// Init our SPI controller (must be before screen and lora)
initSPI();
#ifdef NO_ESP32
#ifndef ARCH_ESP32
SPI.begin();
#else
// ESP32
@@ -290,14 +299,14 @@ void setup()
setupModules();
// Do this after service.init (because that clears error_code)
#ifdef AXP192_SLAVE_ADDRESS
if (!axp192_found)
RECORD_CRITICALERROR(CriticalErrorCode_NoAXP192); // Record a hardware fault for missing hardware
#ifdef HAS_PMU
if (!pmu_found)
RECORD_CRITICALERROR(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)
#if defined(ST7735_CS) || defined(HAS_EINK) || defined(ILI9341_DRIVER)
#if defined(ST7735_CS) || defined(USE_EINK) || defined(ILI9341_DRIVER)
screen->setup();
#else
if (screen_found)
@@ -313,7 +322,7 @@ void setup()
DEBUG_MSG("GPS FactoryReset requested\n");
if (gps->factoryReset()) { // If we don't succeed try again next time
devicestate.did_gps_reset = true;
nodeDB.saveToDisk();
nodeDB.saveToDisk(SEGMENT_DEVICESTATE);
}
}
@@ -377,7 +386,7 @@ void setup()
}
#endif
#ifdef USE_SIM_RADIO
#ifdef ARCH_PORTDUINO
if (!rIf) {
rIf = new SimRadio;
if (!rIf->init()) {
@@ -390,27 +399,27 @@ void setup()
}
#endif
#if defined(PORTDUINO) || defined(HAS_WIFI)
#if HAS_WIFI
mqttInit();
#endif
// Initialize Wifi
initWifi(forceSoftAP);
#ifndef NO_ESP32
#ifdef ARCH_ESP32
// Start web server thread.
webServerThread = new WebServerThread();
#endif
#ifdef PORTDUINO
initApiServer();
#ifdef ARCH_PORTDUINO
initApiServer(TCPPort);
#endif
// Start airtime logger thread.
airTime = new AirTime();
if (!rIf)
RECORD_CRITICALERROR(CriticalErrorCode_NoRadio);
RECORD_CRITICALERROR(CriticalErrorCode_NO_RADIO);
else {
router->addInterface(rIf);
@@ -443,10 +452,10 @@ void loop()
// heap_caps_check_integrity_all(true); // FIXME - disable this expensive check
#ifndef NO_ESP32
#ifdef ARCH_ESP32
esp32Loop();
#endif
#ifdef NRF52_SERIES
#ifdef ARCH_NRF52
nrf52Loop();
#endif
powerCommandsCheck();
+7 -2
View File
@@ -1,22 +1,27 @@
#pragma once
#include <map>
#include "GPSStatus.h"
#include "NodeStatus.h"
#include "PowerStatus.h"
#include "graphics/Screen.h"
#include "mesh/generated/telemetry.pb.h"
extern uint8_t screen_found;
extern uint8_t screen_model;
extern uint8_t cardkb_found;
extern uint8_t kb_model;
extern uint8_t faceskb_found;
extern uint8_t rtc_found;
extern bool eink_found;
extern bool axp192_found;
extern bool pmu_found;
extern bool isCharging;
extern bool isUSBPowered;
extern uint8_t nodeTelemetrySensorsMap[TelemetrySensorType_LPS22+1];
extern int TCPPort; // set by Portduino
// Global Screen singleton.
extern graphics::Screen *screen;
// extern Observable<meshtastic::PowerStatus> newPowerStatus; //TODO: move this to main-esp32.cpp somehow or a helper class
+11 -11
View File
@@ -85,7 +85,7 @@ void Channels::initDefaultChannel(ChannelIndex chIndex)
ChannelSettings &channelSettings = ch.settings;
Config_LoRaConfig &loraConfig = config.lora;
loraConfig.modem_preset = Config_LoRaConfig_ModemPreset_LongFast; // Default to Long Range & Fast
loraConfig.modem_preset = Config_LoRaConfig_ModemPreset_LONG_FAST; // Default to Long Range & Fast
loraConfig.tx_power = 0; // default
uint8_t defaultpskIndex = 1;
@@ -211,28 +211,28 @@ const char *Channels::getName(size_t chIndex)
// the app fucked up and forgot to set channelSettings.name
if (config.lora.bandwidth != 0)
channelName = "Unset";
channelName = "Custom";
else
switch (config.lora.modem_preset) {
case Config_LoRaConfig_ModemPreset_ShortSlow:
case Config_LoRaConfig_ModemPreset_SHORT_SLOW:
channelName = "ShortSlow";
break;
case Config_LoRaConfig_ModemPreset_ShortFast:
case Config_LoRaConfig_ModemPreset_SHORT_FAST:
channelName = "ShortFast";
break;
case Config_LoRaConfig_ModemPreset_MidSlow:
case Config_LoRaConfig_ModemPreset_MEDIUM_SLOW:
channelName = "MediumSlow";
break;
case Config_LoRaConfig_ModemPreset_MidFast:
case Config_LoRaConfig_ModemPreset_MEDIUM_FAST:
channelName = "MediumFast";
break;
case Config_LoRaConfig_ModemPreset_LongFast:
channelName = "LongFast";
break;
case Config_LoRaConfig_ModemPreset_LongSlow:
case Config_LoRaConfig_ModemPreset_LONG_SLOW:
channelName = "LongSlow";
break;
case Config_LoRaConfig_ModemPreset_VLongSlow:
case Config_LoRaConfig_ModemPreset_LONG_FAST:
channelName = "LongFast";
break;
case Config_LoRaConfig_ModemPreset_VERY_LONG_SLOW:
channelName = "VLongSlow";
break;
default:
+1 -7
View File
@@ -3,11 +3,7 @@
void CryptoEngine::setKey(const CryptoKey &k)
{
DEBUG_MSG("Installing AES%d key!\n", k.length * 8);
/* for(uint8_t i = 0; i < k.length; i++)
DEBUG_MSG("%02x ", k.bytes[i]);
DEBUG_MSG("\n"); */
DEBUG_MSG("Using AES%d key!\n", k.length * 8);
key = k;
}
@@ -36,6 +32,4 @@ void CryptoEngine::initNonce(uint32_t fromNode, uint64_t packetId)
// use memcpy to avoid breaking strict-aliasing
memcpy(nonce, &packetId, sizeof(uint64_t));
memcpy(nonce + sizeof(uint64_t), &fromNode, sizeof(uint32_t));
//*((uint64_t *)&nonce[0]) = packetId;
//*((uint32_t *)&nonce[8]) = fromNode;
}
+7 -3
View File
@@ -29,10 +29,14 @@ bool FloodingRouter::shouldFilterReceived(MeshPacket *p)
void FloodingRouter::sniffReceived(const MeshPacket *p, const Routing *c)
{
if ((p->to == NODENUM_BROADCAST) && (p->hop_limit > 0) && (getFrom(p) != getNodeNum())) {
PacketId ackId = ((c && c->error_reason == Routing_Error_NONE) || !c) ? p->decoded.request_id : 0;
if (ackId && p->to != getNodeNum()) {
// do not flood direct message that is ACKed
DEBUG_MSG("Receiving an ACK not for me, but don't need to rebroadcast this direct message anymore.\n");
Router::cancelSending(p->to, p->decoded.request_id); // cancel rebroadcast for this DM
} else if ((p->to != getNodeNum()) && (p->hop_limit > 0) && (getFrom(p) != getNodeNum())) {
if (p->id != 0) {
if (config.device.role != Config_DeviceConfig_Role_ClientMute) {
if (config.device.role != Config_DeviceConfig_Role_CLIENT_MUTE) {
MeshPacket *tosend = packetPool.allocCopy(*p); // keep a copy because we will be sending it
tosend->hop_limit--; // bump down the hop count
+4 -4
View File
@@ -72,7 +72,7 @@ void MeshModule::callPlugins(const MeshPacket &mp, RxSource src)
bool moduleFound = false;
// We now allow **encrypted** packets to pass through the modules
bool isDecoded = mp.which_payloadVariant == MeshPacket_decoded_tag;
bool isDecoded = mp.which_payload_variant == MeshPacket_decoded_tag;
currentReply = NULL; // No reply yet
@@ -112,7 +112,7 @@ void MeshModule::callPlugins(const MeshPacket &mp, RxSource src)
bool rxChannelOk = !pi.boundChannel || (mp.from == 0) ||
!ch ||
strlen(ch->settings.name) > 0 ||
strcmp(ch->settings.name, pi.boundChannel);
(strcmp(ch->settings.name, pi.boundChannel) == 0);
if (!rxChannelOk) {
// no one should have already replied!
@@ -211,7 +211,7 @@ void MeshModule::sendResponse(const MeshPacket &req)
*/
void setReplyTo(MeshPacket *p, const MeshPacket &to)
{
assert(p->which_payloadVariant == MeshPacket_decoded_tag); // Should already be set by now
assert(p->which_payload_variant == MeshPacket_decoded_tag); // Should already be set by now
p->to = getFrom(&to); // Make sure that if we are sending to the local node, we use our local node addr, not 0
p->channel = to.channel; // Use the same channel that the request came in on
@@ -266,7 +266,7 @@ AdminMessageHandleResult MeshModule::handleAdminMessageForAllPlugins(const MeshP
// In case we have a response it always has priority.
DEBUG_MSG("Reply prepared by module '%s' of variant: %d\n",
pi.name,
response->which_variant);
response->which_payload_variant);
handled = h;
}
else if ((handled != AdminMessageHandleResult::HANDLED_WITH_RESPONSE) &&
+2 -2
View File
@@ -4,7 +4,7 @@
#include "mesh/MeshTypes.h"
#include <vector>
#ifndef NO_SCREEN
#if HAS_SCREEN
#include <OLEDDisplay.h>
#include <OLEDDisplayUi.h>
#endif
@@ -72,7 +72,7 @@ class MeshModule
static void observeUIEvents(Observer<const UIFrameEvent *> *observer);
static AdminMessageHandleResult handleAdminMessageForAllPlugins(
const MeshPacket &mp, AdminMessage *request, AdminMessage *response);
#ifndef NO_SCREEN
#if HAS_SCREEN
virtual void drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) { return; }
#endif
protected:
+32 -5
View File
@@ -16,6 +16,10 @@
#include "modules/PositionModule.h"
#include "power.h"
#ifdef ARCH_ESP32
#include "nimble/NimbleBluetooth.h"
#endif
/*
receivedPacketQueue - this is a queue of messages we've received from the mesh, which we are keeping to deliver to the phone.
It is implemented with a FreeRTos queue (wrapped with a little RTQueue class) of pointers to MeshPacket protobufs (which were
@@ -86,7 +90,7 @@ void MeshService::loop()
}
/// The radioConfig object just changed, call this to force the hw to change to the new settings
bool MeshService::reloadConfig()
bool MeshService::reloadConfig(int saveWhat)
{
// If we can successfully set this radio to these settings, save them to disk
@@ -94,7 +98,7 @@ bool MeshService::reloadConfig()
bool didReset = nodeDB.resetRadioConfig(); // Don't let the phone send us fatally bad settings
configChanged.notifyObservers(NULL); // This will cause radio hardware to change freqs etc
nodeDB.saveToDisk();
nodeDB.saveToDisk(saveWhat);
return didReset;
}
@@ -109,7 +113,7 @@ void MeshService::reloadOwner()
// update everyone else
if (nodeInfoModule)
nodeInfoModule->sendOurNodeInfo();
nodeDB.saveToDisk();
nodeDB.saveToDisk(SEGMENT_DEVICESTATE);
}
/**
@@ -119,6 +123,29 @@ void MeshService::reloadOwner()
*/
void MeshService::handleToRadio(MeshPacket &p)
{
#ifdef ARCH_PORTDUINO
// Simulates device is receiving a packet via the LoRa chip
if (p.decoded.portnum == PortNum_SIMULATOR_APP) {
// Simulator packet (=Compressed packet) is encapsulated in a MeshPacket, so need to unwrap first
Compressed scratch;
Compressed *decoded = NULL;
if (p.which_payload_variant == MeshPacket_decoded_tag) {
memset(&scratch, 0, sizeof(scratch));
p.decoded.payload.size = pb_decode_from_bytes(p.decoded.payload.bytes, p.decoded.payload.size, &Compressed_msg, &scratch);
if (p.decoded.payload.size) {
decoded = &scratch;
// Extract the original payload and replace
memcpy(&p.decoded.payload, &decoded->data, sizeof(decoded->data));
// Switch the port from PortNum_SIMULATOR_APP back to the original PortNum
p.decoded.portnum = decoded->portnum;
} else
DEBUG_MSG("Error decoding protobuf for simulator message!\n");
}
// Let SimRadio receive as if it did via its LoRa chip
SimRadio::instance->startReceive(&p);
return;
}
#endif
if (p.from != 0) { // We don't let phones assign nodenums to their sent messages
DEBUG_MSG("Warning: phone tried to pick a nodenum, we don't allow that.\n");
p.from = 0;
@@ -168,7 +195,7 @@ void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies)
NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
assert(node);
if (node->has_position) {
if (node->has_position && (node->position.latitude_i != 0 || node->position.longitude_i != 0)) {
if (positionModule) {
DEBUG_MSG("Sending position ping to 0x%x, wantReplies=%d\n", dest, wantReplies);
positionModule->sendOurPosition(dest, wantReplies);
@@ -248,7 +275,7 @@ int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus)
pos.time = getValidTime(RTCQualityGPS);
// In debug logs, identify position by @timestamp:stage (stage 4 = nodeDB)
DEBUG_MSG("onGPSChanged() pos@%x, time=%u, lat=%d, lon=%d, alt=%d\n", pos.pos_timestamp, pos.time, pos.latitude_i,
DEBUG_MSG("onGPSChanged() pos@%x, time=%u, lat=%d, lon=%d, alt=%d\n", pos.timestamp, pos.time, pos.latitude_i,
pos.longitude_i, pos.altitude);
// Update our current position in the local DB
+4 -1
View File
@@ -10,6 +10,9 @@
#include "MeshTypes.h"
#include "Observer.h"
#include "PointerQueue.h"
#ifdef ARCH_PORTDUINO
#include "../platform/portduino/SimRadio.h"
#endif
/**
* Top level app for this service. keeps the mesh, the radio config and the queue of received packets.
@@ -63,7 +66,7 @@ class MeshService
/** The radioConfig object just changed, call this to force the hw to change to the new settings
* @return true if client devices should be sent a new set of radio configs
*/
bool reloadConfig();
bool reloadConfig(int saveWhat=SEGMENT_CONFIG | SEGMENT_MODULECONFIG | SEGMENT_DEVICESTATE | SEGMENT_CHANNELS);
/// The owner User record just got updated, update our node DB and broadcast the info into the mesh
void reloadOwner();
+195 -108
View File
@@ -16,15 +16,16 @@
#include "mesh-pb-constants.h"
#include <pb_decode.h>
#include <pb_encode.h>
#include <ErriezCRC32.h>
#ifndef NO_ESP32
#ifdef ARCH_ESP32
#include "mesh/http/WiFiAPClient.h"
#include "modules/esp32/StoreForwardModule.h"
#include <Preferences.h>
#include <nvs_flash.h>
#endif
#ifdef NRF52_SERIES
#ifdef ARCH_NRF52
#include <bluefruit.h>
#include <utility/bonding.h>
#endif
@@ -43,14 +44,6 @@ ChannelFile channelFile;
*/
uint32_t radioGeneration;
/*
DeviceState versions used to be defined in the .proto file but really only this function cares. So changed to a
#define here.
*/
#define DEVICESTATE_CUR_VER 11
#define DEVICESTATE_MIN_VER DEVICESTATE_CUR_VER
// FIXME - move this somewhere else
extern void getMacAddr(uint8_t *dmac);
@@ -81,35 +74,14 @@ NodeNum getFrom(const MeshPacket *p)
return (p->from == 0) ? nodeDB.getNodeNum() : p->from;
}
bool NodeDB::resetRadioConfig()
bool NodeDB::resetRadioConfig(bool factory_reset)
{
bool didFactoryReset = false;
radioGeneration++;
// radioConfig.has_preferences = true;
if (config.device.factory_reset) {
DEBUG_MSG("Performing factory reset!\n");
installDefaultDeviceState();
#ifndef NO_ESP32
// This will erase what's in NVS including ssl keys, persistant variables and ble pairing
nvs_flash_erase();
#endif
#ifdef NRF52_SERIES
// first, remove the "/prefs" (this removes most prefs)
FSCom.rmdir_r("/prefs");
// second, install default state (this will deal with the duplicate mac address issue)
installDefaultDeviceState();
// third, write to disk
saveToDisk();
Bluefruit.begin();
DEBUG_MSG("Clearing bluetooth bonds!\n");
bond_print_list(BLE_GAP_ROLE_PERIPH);
bond_print_list(BLE_GAP_ROLE_CENTRAL);
Bluefruit.Periph.clearBonds();
Bluefruit.Central.clearBonds();
#endif
didFactoryReset = true;
if (factory_reset) {
didFactoryReset = factoryReset();
}
if (channelFile.channels_count != MAX_NUM_CHANNELS) {
@@ -140,63 +112,134 @@ bool NodeDB::resetRadioConfig()
// Update the global myRegion
initRegion();
if (didFactoryReset) {
DEBUG_MSG("Rebooting due to factory reset");
screen->startRebootScreen();
rebootAtMsec = millis() + (5 * 1000);
}
return didFactoryReset;
}
bool NodeDB::factoryReset()
{
DEBUG_MSG("Performing factory reset!\n");
// first, remove the "/prefs" (this removes most prefs)
rmDir("/prefs");
// second, install default state (this will deal with the duplicate mac address issue)
installDefaultDeviceState();
installDefaultConfig();
// third, write everything to disk
saveToDisk();
#ifdef ARCH_ESP32
// This will erase what's in NVS including ssl keys, persistant variables and ble pairing
nvs_flash_erase();
#endif
#ifdef ARCH_NRF52
Bluefruit.begin();
DEBUG_MSG("Clearing bluetooth bonds!\n");
bond_print_list(BLE_GAP_ROLE_PERIPH);
bond_print_list(BLE_GAP_ROLE_CENTRAL);
Bluefruit.Periph.clearBonds();
Bluefruit.Central.clearBonds();
#endif
return true;
}
void NodeDB::installDefaultConfig()
{
DEBUG_MSG("Installing default LocalConfig\n");
memset(&config, 0, sizeof(LocalConfig));
config.version = DEVICESTATE_CUR_VER;
config.has_device = true;
config.has_display = true;
config.has_lora = true;
config.has_position = true;
config.has_power = true;
config.has_wifi = true;
config.lora.region = Config_LoRaConfig_RegionCode_Unset;
config.lora.modem_preset = Config_LoRaConfig_ModemPreset_LongFast;
config.has_network = true;
config.has_bluetooth = true;
config.lora.tx_enabled = true; // FIXME: maybe false in the future, and setting region to enable it. (unset region forces it off)
config.lora.region = Config_LoRaConfig_RegionCode_UNSET;
config.lora.modem_preset = Config_LoRaConfig_ModemPreset_LONG_FAST;
config.lora.hop_limit = HOP_RELIABLE;
config.position.gps_enabled = true;
config.position.position_broadcast_smart_enabled = true;
config.device.serial_enabled = true;
resetRadioConfig();
strncpy(config.device.ntp_server, "0.pool.ntp.org", 32);
strncpy(config.network.ntp_server, "0.pool.ntp.org", 32);
// FIXME: Default to bluetooth capability of platform as default
config.bluetooth.enabled = true;
config.bluetooth.fixed_pin = defaultBLEPin;
#if defined(ST7735_CS) || defined(USE_EINK) || defined(ILI9341_DRIVER)
bool hasScreen = true;
#else
bool hasScreen = screen_found;
#endif
config.bluetooth.mode = hasScreen ? Config_BluetoothConfig_PairingMode_RANDOM_PIN : Config_BluetoothConfig_PairingMode_FIXED_PIN;
// for backward compat, default position flags are ALT+MSL
config.position.position_flags =
(Config_PositionConfig_PositionFlags_POS_ALTITUDE | Config_PositionConfig_PositionFlags_POS_ALT_MSL);
config.position.position_flags = (Config_PositionConfig_PositionFlags_ALTITUDE | Config_PositionConfig_PositionFlags_ALTITUDE_MSL);
initConfigIntervals();
}
void NodeDB::initConfigIntervals()
{
config.position.gps_update_interval = default_gps_update_interval;
config.position.gps_attempt_time = default_gps_attempt_time;
config.position.position_broadcast_secs = default_broadcast_interval_secs;
config.power.ls_secs = default_ls_secs;
config.power.mesh_sds_timeout_secs = default_mesh_sds_timeout_secs;
config.power.min_wake_secs = default_min_wake_secs;
config.power.sds_secs = default_sds_secs;
config.power.wait_bluetooth_secs = default_wait_bluetooth_secs;
config.display.screen_on_secs = default_screen_on_secs;
}
void NodeDB::installDefaultModuleConfig()
{
DEBUG_MSG("Installing default ModuleConfig\n");
memset(&moduleConfig, 0, sizeof(ModuleConfig));
moduleConfig.has_canned_message = true;
moduleConfig.has_external_notification = true;
moduleConfig.version = DEVICESTATE_CUR_VER;
moduleConfig.has_mqtt = true;
moduleConfig.has_range_test = true;
moduleConfig.has_serial = true;
moduleConfig.has_store_forward = true;
moduleConfig.has_telemetry = true;
moduleConfig.has_external_notification = true;
moduleConfig.has_canned_message = true;
initModuleConfigIntervals();
}
// void NodeDB::installDefaultRadioConfig()
// {
// memset(&radioConfig, 0, sizeof(radioConfig));
// radioConfig.has_preferences = true;
// resetRadioConfig();
// // for backward compat, default position flags are BAT+ALT+MSL (0x23 = 35)
// config.position.position_flags =
// (Config_PositionConfig_PositionFlags_POS_BATTERY | Config_PositionConfig_PositionFlags_POS_ALTITUDE |
// Config_PositionConfig_PositionFlags_POS_ALT_MSL);
// }
void NodeDB::initModuleConfigIntervals()
{
moduleConfig.telemetry.device_update_interval = default_broadcast_interval_secs;
moduleConfig.telemetry.environment_update_interval = default_broadcast_interval_secs;
}
void NodeDB::installDefaultChannels()
{
DEBUG_MSG("Installing default ChannelFile\n");
memset(&channelFile, 0, sizeof(ChannelFile));
channelFile.version = DEVICESTATE_CUR_VER;
}
void NodeDB::resetNodes()
{
devicestate.node_db_count = 0;
memset(devicestate.node_db, 0, sizeof(devicestate.node_db));
saveDeviceStateToDisk();
}
void NodeDB::installDefaultDeviceState()
{
DEBUG_MSG("Installing default DeviceState\n");
memset(&devicestate, 0, sizeof(DeviceState));
*numNodes = 0; // Forget node DB
*numNodes = 0;
// init our devicestate with valid flags so protobuf writing/reading will work
devicestate.has_my_node = true;
devicestate.has_owner = true;
@@ -214,28 +257,27 @@ void NodeDB::installDefaultDeviceState()
// Set default owner name
pickNewNodeNum(); // based on macaddr now
sprintf(owner.long_name, "Unknown %02x%02x", ourMacAddr[4], ourMacAddr[5]);
sprintf(owner.short_name, "?%02X", (unsigned)(myNodeInfo.my_node_num & 0xff));
sprintf(owner.long_name, "Meshtastic %02x%02x", ourMacAddr[4], ourMacAddr[5]);
sprintf(owner.short_name, "%02x%02x", ourMacAddr[4], ourMacAddr[5]);
sprintf(owner.id, "!%08x", getNodeNum()); // Default node ID now based on nodenum
memcpy(owner.macaddr, ourMacAddr, sizeof(owner.macaddr));
installDefaultChannels();
installDefaultConfig();
}
void NodeDB::init()
{
installDefaultDeviceState();
// saveToDisk();
DEBUG_MSG("Initializing NodeDB\n");
loadFromDisk();
// saveToDisk();
uint32_t devicestateCRC = crc32Buffer(&devicestate, sizeof(devicestate));
uint32_t configCRC = crc32Buffer(&config, sizeof(config));
uint32_t channelFileCRC = crc32Buffer(&channelFile, sizeof(channelFile));
int saveWhat = 0;
myNodeInfo.max_channels = MAX_NUM_CHANNELS; // tell others the max # of channels we can understand
myNodeInfo.error_code =
CriticalErrorCode_None; // For the error code, only show values from this boot (discard value from flash)
myNodeInfo.error_code = CriticalErrorCode_NONE; // For the error code, only show values from this boot (discard value from flash)
myNodeInfo.error_address = 0;
// likewise - we always want the app requirements to come from the running appload
@@ -255,7 +297,7 @@ void NodeDB::init()
strncpy(myNodeInfo.firmware_version, optstr(APP_VERSION), sizeof(myNodeInfo.firmware_version));
#ifndef NO_ESP32
#ifdef ARCH_ESP32
Preferences preferences;
preferences.begin("meshtastic", false);
myNodeInfo.reboot_count = preferences.getUInt("rebootCounter", 0);
@@ -269,8 +311,16 @@ void NodeDB::init()
#endif
resetRadioConfig(); // If bogus settings got saved, then fix them
DEBUG_MSG("region=%d, NODENUM=0x%x, dbsize=%d\n", config.lora.region, myNodeInfo.my_node_num, *numNodes);
if (devicestateCRC != crc32Buffer(&devicestate, sizeof(devicestate)))
saveWhat |= SEGMENT_DEVICESTATE;
if (configCRC != crc32Buffer(&config, sizeof(config)))
saveWhat |= SEGMENT_CONFIG;
if (channelFileCRC != crc32Buffer(&channelFile, sizeof(channelFile)))
saveWhat |= SEGMENT_CHANNELS;
saveToDisk(saveWhat);
}
// We reserve a few nodenums for future use
@@ -300,20 +350,20 @@ void NodeDB::pickNewNodeNum()
myNodeInfo.my_node_num = r;
}
static const char *preffile = "/prefs/db.proto";
static const char *configfile = "/prefs/config.proto";
static const char *moduleConfigfile = "/prefs/module.proto";
static const char *channelfile = "/prefs/channels.proto";
static const char *prefFileName = "/prefs/db.proto";
static const char *configFileName = "/prefs/config.proto";
static const char *moduleConfigFileName = "/prefs/module.proto";
static const char *channelFileName = "/prefs/channels.proto";
/** Load a protobuf from a file, return true for success */
bool loadProto(const char *filename, size_t protoSize, size_t objSize, const pb_msgdesc_t *fields, void *dest_struct)
{
bool okay = false;
#ifdef FSCom
// static DeviceState scratch; We no longer read into a tempbuf because this structure is 15KB of valuable RAM
auto f = FSCom.open(filename);
auto f = FSCom.open(filename, FILE_O_READ);
bool okay = false;
if (f) {
DEBUG_MSG("Loading %s\n", filename);
pb_istream_t stream = {&readcb, &f, protoSize};
@@ -340,39 +390,60 @@ bool loadProto(const char *filename, size_t protoSize, size_t objSize, const pb_
void NodeDB::loadFromDisk()
{
// static DeviceState scratch; We no longer read into a tempbuf because this structure is 15KB of valuable RAM
if (!loadProto(preffile, DeviceState_size, sizeof(devicestate), DeviceState_fields, &devicestate)) {
if (!loadProto(prefFileName, DeviceState_size, sizeof(devicestate), DeviceState_fields, &devicestate)) {
installDefaultDeviceState(); // Our in RAM copy might now be corrupt
} else {
if (devicestate.version < DEVICESTATE_MIN_VER) {
DEBUG_MSG("Warn: devicestate %d is old, discarding\n", devicestate.version);
installDefaultDeviceState();
factoryReset();
} else {
DEBUG_MSG("Loaded saved preferences version %d\n", devicestate.version);
DEBUG_MSG("Loaded saved devicestate version %d\n", devicestate.version);
}
}
if (!loadProto(configfile, LocalConfig_size, sizeof(LocalConfig), LocalConfig_fields, &config)) {
if (!loadProto(configFileName, LocalConfig_size, sizeof(LocalConfig), LocalConfig_fields, &config)) {
installDefaultConfig(); // Our in RAM copy might now be corrupt
} else {
if (config.version < DEVICESTATE_MIN_VER) {
DEBUG_MSG("Warn: config %d is old, discarding\n", config.version);
installDefaultConfig();
} else {
DEBUG_MSG("Loaded saved config version %d\n", config.version);
}
}
if (!loadProto(moduleConfigfile, LocalModuleConfig_size, sizeof(LocalModuleConfig), LocalModuleConfig_fields, &moduleConfig)) {
if (!loadProto(moduleConfigFileName, LocalModuleConfig_size, sizeof(LocalModuleConfig), LocalModuleConfig_fields, &moduleConfig)) {
installDefaultModuleConfig(); // Our in RAM copy might now be corrupt
} else {
if (moduleConfig.version < DEVICESTATE_MIN_VER) {
DEBUG_MSG("Warn: moduleConfig %d is old, discarding\n", moduleConfig.version);
installDefaultModuleConfig();
} else {
DEBUG_MSG("Loaded saved moduleConfig version %d\n", moduleConfig.version);
}
}
if (!loadProto(channelfile, ChannelFile_size, sizeof(ChannelFile), ChannelFile_fields, &channelFile)) {
if (!loadProto(channelFileName, ChannelFile_size, sizeof(ChannelFile), ChannelFile_fields, &channelFile)) {
installDefaultChannels(); // Our in RAM copy might now be corrupt
} else {
if (channelFile.version < DEVICESTATE_MIN_VER) {
DEBUG_MSG("Warn: channelFile %d is old, discarding\n", channelFile.version);
installDefaultChannels();
} else {
DEBUG_MSG("Loaded saved channelFile version %d\n", channelFile.version);
}
}
}
/** Save a protobuf from a file, return true for success */
bool saveProto(const char *filename, size_t protoSize, size_t objSize, const pb_msgdesc_t *fields, const void *dest_struct)
{
bool okay = false;
#ifdef FSCom
// static DeviceState scratch; We no longer read into a tempbuf because this structure is 15KB of valuable RAM
String filenameTmp = filename;
filenameTmp += ".tmp";
auto f = FSCom.open(filenameTmp.c_str(), FILE_O_WRITE);
bool okay = false;
if (f) {
DEBUG_MSG("Saving %s\n", filename);
pb_ostream_t stream = {&writecb, &f, protoSize};
@@ -382,13 +453,12 @@ bool saveProto(const char *filename, size_t protoSize, size_t objSize, const pb_
} else {
okay = true;
}
f.close();
// brief window of risk here ;-)
if (FSCom.exists(filename) && !FSCom.remove(filename))
DEBUG_MSG("Warning: Can't remove old pref file\n");
if (!FSCom.rename(filenameTmp.c_str(), filename))
if (!renameFile(filenameTmp.c_str(), filename))
DEBUG_MSG("Error: can't rename new pref file\n");
} else {
DEBUG_MSG("Can't write prefs\n");
@@ -405,38 +475,55 @@ void NodeDB::saveChannelsToDisk()
#ifdef FSCom
FSCom.mkdir("/prefs");
#endif
saveProto(channelfile, ChannelFile_size, sizeof(ChannelFile), ChannelFile_fields, &channelFile);
saveProto(channelFileName, ChannelFile_size, sizeof(channelFile), ChannelFile_fields, &channelFile);
}
}
void NodeDB::saveToDisk()
void NodeDB::saveDeviceStateToDisk()
{
if (!devicestate.no_save) {
#ifdef FSCom
FSCom.mkdir("/prefs");
#endif
saveProto(preffile, DeviceState_size, sizeof(devicestate), DeviceState_fields, &devicestate);
saveProto(prefFileName, DeviceState_size, sizeof(devicestate), DeviceState_fields, &devicestate);
}
}
// save all config segments
config.has_device = true;
config.has_display = true;
config.has_lora = true;
config.has_position = true;
config.has_power = true;
config.has_wifi = true;
saveProto(configfile, LocalConfig_size, sizeof(LocalConfig), LocalConfig_fields, &config);
void NodeDB::saveToDisk(int saveWhat)
{
if (!devicestate.no_save) {
#ifdef FSCom
FSCom.mkdir("/prefs");
#endif
if (saveWhat & SEGMENT_DEVICESTATE) {
saveDeviceStateToDisk();
}
moduleConfig.has_canned_message = true;
moduleConfig.has_external_notification = true;
moduleConfig.has_mqtt = true;
moduleConfig.has_range_test = true;
moduleConfig.has_serial = true;
moduleConfig.has_store_forward = true;
moduleConfig.has_telemetry = true;
saveProto(moduleConfigfile, LocalModuleConfig_size, sizeof(LocalModuleConfig), LocalModuleConfig_fields, &moduleConfig);
if (saveWhat & SEGMENT_CONFIG) {
config.has_device = true;
config.has_display = true;
config.has_lora = true;
config.has_position = true;
config.has_power = true;
config.has_network = true;
config.has_bluetooth = true;
saveProto(configFileName, LocalConfig_size, sizeof(config), LocalConfig_fields, &config);
}
saveChannelsToDisk();
if (saveWhat & SEGMENT_MODULECONFIG) {
moduleConfig.has_canned_message = true;
moduleConfig.has_external_notification = true;
moduleConfig.has_mqtt = true;
moduleConfig.has_range_test = true;
moduleConfig.has_serial = true;
moduleConfig.has_store_forward = true;
moduleConfig.has_telemetry = true;
saveProto(moduleConfigFileName, LocalModuleConfig_size, sizeof(moduleConfig), LocalModuleConfig_fields, &moduleConfig);
}
if (saveWhat & SEGMENT_CHANNELS) {
saveChannelsToDisk();
}
} else {
DEBUG_MSG("***** DEVELOPMENT MODE - DO NOT RELEASE - not saving to flash *****\n");
}
@@ -489,11 +576,11 @@ void NodeDB::updatePosition(uint32_t nodeId, const Position &p, RxSource src)
if (src == RX_SRC_LOCAL) {
// Local packet, fully authoritative
DEBUG_MSG("updatePosition LOCAL pos@%x, time=%u, latI=%d, lonI=%d, alt=%d\n", p.pos_timestamp, p.time, p.latitude_i,
DEBUG_MSG("updatePosition LOCAL pos@%x, time=%u, latI=%d, lonI=%d, alt=%d\n", p.timestamp, p.time, p.latitude_i,
p.longitude_i, p.altitude);
info->position = p;
} else if ((p.time > 0) && !p.latitude_i && !p.longitude_i && !p.pos_timestamp && !p.location_source) {
} else if ((p.time > 0) && !p.latitude_i && !p.longitude_i && !p.timestamp && !p.location_source) {
// FIXME SPECIAL TIME SETTING PACKET FROM EUD TO RADIO
// (stop-gap fix for issue #900)
DEBUG_MSG("updatePosition SPECIAL time setting time=%u\n", p.time);
@@ -578,7 +665,7 @@ void NodeDB::updateUser(uint32_t nodeId, const User &p)
/// we updateGUI and updateGUIforNode if we think our this change is big enough for a redraw
void NodeDB::updateFrom(const MeshPacket &mp)
{
if (mp.which_payloadVariant == MeshPacket_decoded_tag && mp.from) {
if (mp.which_payload_variant == MeshPacket_decoded_tag && mp.from) {
DEBUG_MSG("Update DB node 0x%x, rx_time=%u\n", mp.from, mp.rx_time);
NodeInfo *info = getOrCreateNode(getFrom(&mp));
@@ -644,7 +731,7 @@ void recordCriticalError(CriticalErrorCode code, uint32_t address, const char *f
myNodeInfo.error_count++;
// Currently portuino is mostly used for simulation. Make sue the user notices something really bad happend
#ifdef PORTDUINO
#ifdef ARCH_PORTDUINO
DEBUG_MSG("A critical failure occurred, portduino is exiting...");
exit(2);
#endif
+40 -14
View File
@@ -8,6 +8,19 @@
#include "NodeStatus.h"
#include "mesh-pb-constants.h"
/*
DeviceState versions used to be defined in the .proto file but really only this function cares. So changed to a
#define here.
*/
#define SEGMENT_CONFIG 1
#define SEGMENT_MODULECONFIG 2
#define SEGMENT_DEVICESTATE 4
#define SEGMENT_CHANNELS 8
#define DEVICESTATE_CUR_VER 19
#define DEVICESTATE_MIN_VER DEVICESTATE_CUR_VER
extern DeviceState devicestate;
extern ChannelFile channelFile;
extern MyNodeInfo &myNodeInfo;
@@ -44,7 +57,7 @@ class NodeDB
void init();
/// write to flash
void saveToDisk(), saveChannelsToDisk();
void saveToDisk(int saveWhat=SEGMENT_CONFIG | SEGMENT_MODULECONFIG | SEGMENT_DEVICESTATE | SEGMENT_CHANNELS), saveChannelsToDisk(), saveDeviceStateToDisk();
/** Reinit radio config if needed, because either:
* a) sometimes a buggy android app might send us bogus settings or
@@ -52,7 +65,7 @@ class NodeDB
*
* @return true if the config was completely reset, in that case, we should send it back to the client
*/
bool resetRadioConfig();
bool resetRadioConfig(bool factory_reset = false);
/// given a subpacket sniffed from the network, update our DB state
/// we updateGUI and updateGUIforNode if we think our this change is big enough for a redraw
@@ -107,6 +120,10 @@ class NodeDB
/// Return the number of nodes we've heard from recently (within the last 2 hrs?)
size_t getNumOnlineNodes();
void initConfigIntervals(), initModuleConfigIntervals(), resetNodes();
bool factoryReset();
private:
/// Find a node in our DB, create an empty NodeInfo if missing
NodeInfo *getOrCreateNode(NodeNum n);
@@ -119,6 +136,7 @@ class NodeDB
newStatus.notifyObservers(&status);
}
/// read our db from flash
void loadFromDisk();
@@ -138,7 +156,7 @@ extern NodeDB nodeDB;
/*
If is_router is set, we use a number of different default values
# FIXME - after tuning, move these params into the on-device defaults based on is_router and is_low_power
# FIXME - after tuning, move these params into the on-device defaults based on is_router and is_power_saving
# prefs.position_broadcast_secs = FIXME possibly broadcast only once an hr
prefs.wait_bluetooth_secs = 1 # Don't stay in bluetooth mode
@@ -152,7 +170,7 @@ extern NodeDB nodeDB;
# get a new GPS position once per day
prefs.gps_update_interval = oneday
prefs.is_low_power = True
prefs.is_power_saving = True
# allow up to five minutes for each new GPS lock attempt
prefs.gps_attempt_time = 300
@@ -161,27 +179,35 @@ extern NodeDB nodeDB;
// Our delay functions check for this for times that should never expire
#define NODE_DELAY_FOREVER 0xffffffff
#define IF_ROUTER(routerVal, normalVal) ((config.device.role == Config_DeviceConfig_Role_Router) ? (routerVal) : (normalVal))
#define IF_ROUTER(routerVal, normalVal) ((config.device.role == Config_DeviceConfig_Role_ROUTER) ? (routerVal) : (normalVal))
#define default_broadcast_interval_secs IF_ROUTER(12 * 60 * 60, 15 * 60)
#define ONE_DAY 24 * 60 * 60
#define default_gps_attempt_time IF_ROUTER(5 * 60, 15 * 60)
#define default_gps_update_interval IF_ROUTER(ONE_DAY, 2 * 60)
#define default_broadcast_interval_secs IF_ROUTER(ONE_DAY / 2, 15 * 60)
#define default_wait_bluetooth_secs IF_ROUTER(1, 60)
#define default_mesh_sds_timeout_secs IF_ROUTER(NODE_DELAY_FOREVER, 2 * 60 * 60)
#define default_sds_secs 365 * 24 * 60 * 60
#define default_ls_secs IF_ROUTER(24 * 60 * 60, 5 * 60)
#define default_phone_timeout_secs 15 * 60
#define default_sds_secs IF_ROUTER(ONE_DAY, UINT32_MAX) // Default to forever super deep sleep
#define default_ls_secs IF_ROUTER(ONE_DAY, 5 * 60)
#define default_min_wake_secs 10
#define default_screen_on_secs 60 * 10
inline uint32_t getIntervalOrDefaultMs(uint32_t interval)
inline uint32_t getConfiguredOrDefaultMs(uint32_t configuredInterval)
{
if (interval > 0)
return interval * 1000;
if (configuredInterval > 0) return configuredInterval * 1000;
return default_broadcast_interval_secs * 1000;
}
inline uint32_t getConfiguredOrDefaultMs(uint32_t configuredInterval, uint32_t defaultInterval)
{
if (configuredInterval > 0) return configuredInterval * 1000;
return defaultInterval * 1000;
}
/** The current change # for radio settings. Starts at 0 on boot and any time the radio settings
* might have changed is incremented. Allows others to detect they might now be on a new channel.
*/
extern uint32_t radioGeneration;
#define Module_Config_size (ModuleConfig_CannedMessageConfig_size + ModuleConfig_ExternalNotificationConfig_size + ModuleConfig_MQTTConfig_size + ModuleConfig_RangeTestConfig_size + ModuleConfig_SerialConfig_size + ModuleConfig_StoreForwardConfig_size + ModuleConfig_TelemetryConfig_size + ModuleConfig_size)
#define Module_Config_size (ModuleConfig_CannedMessageConfig_size + ModuleConfig_ExternalNotificationConfig_size + ModuleConfig_MQTTConfig_size + ModuleConfig_RangeTestConfig_size + ModuleConfig_SerialConfig_size + ModuleConfig_StoreForwardConfig_size + ModuleConfig_TelemetryConfig_size + ModuleConfig_size)
+136 -52
View File
@@ -78,21 +78,18 @@ bool PhoneAPI::handleToRadio(const uint8_t *buf, size_t bufLength)
memset(&toRadioScratch, 0, sizeof(toRadioScratch));
if (pb_decode_from_bytes(buf, bufLength, ToRadio_fields, &toRadioScratch)) {
switch (toRadioScratch.which_payloadVariant) {
case ToRadio_packet_tag:
return handleToRadioPacket(toRadioScratch.packet);
case ToRadio_want_config_id_tag:
config_nonce = toRadioScratch.want_config_id;
DEBUG_MSG("Client wants config, nonce=%u\n", config_nonce);
handleStartConfig();
break;
case ToRadio_disconnect_tag:
close();
break;
switch (toRadioScratch.which_payload_variant) {
case ToRadio_packet_tag:
return handleToRadioPacket(toRadioScratch.packet);
case ToRadio_want_config_id_tag:
config_nonce = toRadioScratch.want_config_id;
DEBUG_MSG("Client wants config, nonce=%u\n", config_nonce);
handleStartConfig();
break;
case ToRadio_disconnect_tag:
DEBUG_MSG("Disconnecting from phone\n");
close();
break;
default:
// Ignore nop messages
// DEBUG_MSG("Error: unexpected ToRadio variant\n");
@@ -112,33 +109,32 @@ bool PhoneAPI::handleToRadio(const uint8_t *buf, size_t bufLength)
*
* Our sending states progress in the following sequence (the client app ASSUMES THIS SEQUENCE, DO NOT CHANGE IT):
* STATE_SEND_MY_INFO, // send our my info record
STATE_SEND_RADIO,
STATE_SEND_NODEINFO, // states progress in this order as the device sends to to the client
* STATE_SEND_NODEINFO, // states progress in this order as the device sends to the client
STATE_SEND_CONFIG,
STATE_SEND_COMPLETE_ID,
STATE_SEND_PACKETS // send packets or debug strings
*/
size_t PhoneAPI::getFromRadio(uint8_t *buf)
{
if (!available()) {
// DEBUG_MSG("getFromRadio, !available\n");
// DEBUG_MSG("getFromRadio=not available\n");
return 0;
}
DEBUG_MSG("getFromRadio, state=%d\n", state);
// In case we send a FromRadio packet
memset(&fromRadioScratch, 0, sizeof(fromRadioScratch));
// Advance states as needed
switch (state) {
case STATE_SEND_NOTHING:
DEBUG_MSG("getFromRadio=STATE_SEND_NOTHING\n");
break;
case STATE_SEND_MY_INFO:
DEBUG_MSG("getFromRadio=STATE_SEND_MY_INFO\n");
// If the user has specified they don't want our node to share its location, make sure to tell the phone
// app not to send locations on our behalf.
myNodeInfo.has_gps = gps && gps->isConnected(); // Update with latest GPS connect info
fromRadioScratch.which_payloadVariant = FromRadio_my_info_tag;
fromRadioScratch.which_payload_variant = FromRadio_my_info_tag;
fromRadioScratch.my_info = myNodeInfo;
state = STATE_SEND_NODEINFO;
@@ -146,26 +142,112 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
break;
case STATE_SEND_NODEINFO: {
DEBUG_MSG("getFromRadio=STATE_SEND_NODEINFO\n");
const NodeInfo *info = nodeInfoForPhone;
nodeInfoForPhone = NULL; // We just consumed a nodeinfo, will need a new one next time
if (info) {
DEBUG_MSG("Sending nodeinfo: num=0x%x, lastseen=%u, id=%s, name=%s\n", info->num, info->last_heard, info->user.id,
info->user.long_name);
fromRadioScratch.which_payloadVariant = FromRadio_node_info_tag;
fromRadioScratch.which_payload_variant = FromRadio_node_info_tag;
fromRadioScratch.node_info = *info;
// Stay in current state until done sending nodeinfos
} else {
DEBUG_MSG("Done sending nodeinfos\n");
state = STATE_SEND_COMPLETE_ID;
state = STATE_SEND_CONFIG;
// Go ahead and send that ID right now
return getFromRadio(buf);
}
break;
}
case STATE_SEND_CONFIG:
DEBUG_MSG("getFromRadio=STATE_SEND_CONFIG\n");
fromRadioScratch.which_payload_variant = FromRadio_config_tag;
switch (config_state) {
case Config_device_tag:
fromRadioScratch.config.which_payload_variant = Config_device_tag;
fromRadioScratch.config.payload_variant.device = config.device;
break;
case Config_position_tag:
fromRadioScratch.config.which_payload_variant = Config_position_tag;
fromRadioScratch.config.payload_variant.position = config.position;
break;
case Config_power_tag:
fromRadioScratch.config.which_payload_variant = Config_power_tag;
fromRadioScratch.config.payload_variant.power = config.power;
fromRadioScratch.config.payload_variant.power.ls_secs = default_ls_secs;
break;
case Config_network_tag:
fromRadioScratch.config.which_payload_variant = Config_network_tag;
fromRadioScratch.config.payload_variant.network = config.network;
break;
case Config_display_tag:
fromRadioScratch.config.which_payload_variant = Config_display_tag;
fromRadioScratch.config.payload_variant.display = config.display;
break;
case Config_lora_tag:
fromRadioScratch.config.which_payload_variant = Config_lora_tag;
fromRadioScratch.config.payload_variant.lora = config.lora;
break;
case Config_bluetooth_tag:
fromRadioScratch.config.which_payload_variant = Config_bluetooth_tag;
fromRadioScratch.config.payload_variant.bluetooth = config.bluetooth;
break;
}
// NOTE: The phone app needs to know the ls_secs value so it can properly expect sleep behavior.
// So even if we internally use 0 to represent 'use default' we still need to send the value we are
// using to the app (so that even old phone apps work with new device loads).
config_state++;
// Advance when we have sent all of our config objects
if (config_state > Config_bluetooth_tag) {
state = STATE_SEND_MODULECONFIG;
config_state = ModuleConfig_mqtt_tag;
}
break;
case STATE_SEND_MODULECONFIG:
DEBUG_MSG("getFromRadio=STATE_SEND_MODULECONFIG\n");
fromRadioScratch.which_payload_variant = FromRadio_moduleConfig_tag;
switch (config_state) {
case ModuleConfig_mqtt_tag:
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_mqtt_tag;
fromRadioScratch.moduleConfig.payload_variant.mqtt = moduleConfig.mqtt;
break;
case ModuleConfig_serial_tag:
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_serial_tag;
fromRadioScratch.moduleConfig.payload_variant.serial = moduleConfig.serial;
break;
case ModuleConfig_external_notification_tag:
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_external_notification_tag;
fromRadioScratch.moduleConfig.payload_variant.external_notification = moduleConfig.external_notification;
break;
case ModuleConfig_range_test_tag:
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_range_test_tag;
fromRadioScratch.moduleConfig.payload_variant.range_test = moduleConfig.range_test;
break;
case ModuleConfig_telemetry_tag:
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_telemetry_tag;
fromRadioScratch.moduleConfig.payload_variant.telemetry = moduleConfig.telemetry;
break;
case ModuleConfig_canned_message_tag:
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_canned_message_tag;
fromRadioScratch.moduleConfig.payload_variant.canned_message = moduleConfig.canned_message;
break;
}
config_state++;
// Advance when we have sent all of our ModuleConfig objects
if (config_state > ModuleConfig_canned_message_tag) {
state = STATE_SEND_COMPLETE_ID;
config_state = Config_device_tag;
}
break;
case STATE_SEND_COMPLETE_ID:
fromRadioScratch.which_payloadVariant = FromRadio_config_complete_id_tag;
DEBUG_MSG("getFromRadio=STATE_SEND_COMPLETE_ID\n");
fromRadioScratch.which_payload_variant = FromRadio_config_complete_id_tag;
fromRadioScratch.config_complete_id = config_nonce;
config_nonce = 0;
state = STATE_SEND_PACKETS;
@@ -173,11 +255,12 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
case STATE_SEND_PACKETS:
// Do we have a message from the mesh?
DEBUG_MSG("getFromRadio=STATE_SEND_PACKETS\n");
if (packetForPhone) {
printPacket("phone downloaded packet", packetForPhone);
// Encapsulate as a FromRadio packet
fromRadioScratch.which_payloadVariant = FromRadio_packet_tag;
fromRadioScratch.which_payload_variant = FromRadio_packet_tag;
fromRadioScratch.packet = *packetForPhone;
}
releasePhonePacket();
@@ -188,7 +271,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
}
// Do we have a message from the mesh?
if (fromRadioScratch.which_payloadVariant != 0) {
if (fromRadioScratch.which_payload_variant != 0) {
// Encapsulate as a FromRadio packet
size_t numbytes = pb_encode_to_bytes(buf, FromRadio_size, FromRadio_fields, &fromRadioScratch);
// DEBUG_MSG("encoding toPhone packet to phone variant=%d, %d bytes\n", fromRadioScratch.which_payloadVariant, numbytes);
@@ -199,7 +282,10 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
return 0;
}
void PhoneAPI::handleDisconnect() {}
void PhoneAPI::handleDisconnect()
{
DEBUG_MSG("PhoneAPI disconnect\n");
}
void PhoneAPI::releasePhonePacket()
{
@@ -215,29 +301,27 @@ void PhoneAPI::releasePhonePacket()
bool PhoneAPI::available()
{
switch (state) {
case STATE_SEND_NOTHING:
return false;
case STATE_SEND_MY_INFO:
return true;
case STATE_SEND_NODEINFO:
if (!nodeInfoForPhone)
nodeInfoForPhone = nodeDB.readNextInfo();
return true; // Always say we have something, because we might need to advance our state machine
case STATE_SEND_COMPLETE_ID:
return true;
case STATE_SEND_PACKETS: {
// Try to pull a new packet from the service (if we haven't already)
if (!packetForPhone)
packetForPhone = service.getForPhone();
bool hasPacket = !!packetForPhone;
// DEBUG_MSG("available hasPacket=%d\n", hasPacket);
return hasPacket;
case STATE_SEND_NOTHING:
return false;
case STATE_SEND_MY_INFO:
return true;
case STATE_SEND_CONFIG:
return true;
case STATE_SEND_MODULECONFIG:
return true;
case STATE_SEND_NODEINFO:
if (!nodeInfoForPhone)
nodeInfoForPhone = nodeDB.readNextInfo();
return true; // Always say we have something, because we might need to advance our state machine
case STATE_SEND_COMPLETE_ID:
return true;
case STATE_SEND_PACKETS: {
if (!packetForPhone)
packetForPhone = service.getForPhone();
bool hasPacket = !!packetForPhone;
// DEBUG_MSG("available hasPacket=%d\n", hasPacket);
return hasPacket;
}
default:
assert(0); // unexpected state - FIXME, make an error code and reboot
}
@@ -269,4 +353,4 @@ int PhoneAPI::onNotify(uint32_t newValue)
DEBUG_MSG("(Client not yet interested in packets)\n");
return 0;
}
}
+8 -7
View File
@@ -20,20 +20,19 @@ class PhoneAPI
: public Observer<uint32_t> // FIXME, we shouldn't be inheriting from Observer, instead use CallbackObserver as a member
{
enum State {
STATE_UNUSED, // (no longer used) old default state - until Android apps are all updated, uses the old BLE API
STATE_SEND_NOTHING, // (Eventual) Initial state, don't send anything until the client starts asking for config
// (disconnected)
STATE_SEND_NOTHING, // Initial state, don't send anything until the client starts asking for config
STATE_SEND_MY_INFO, // send our my info record
STATE_SEND_GROUPS,
// STATE_SEND_RADIO, // in 1.2 we now send this as a regular mesh packet
// STATE_SEND_OWNER, no need to send Owner specially, it is just part of the nodedb
STATE_SEND_NODEINFO, // states progress in this order as the device sends to to the client
STATE_SEND_CONFIG, // Replacement for the old Radioconfig
STATE_SEND_MODULECONFIG, // Send Module specific config
STATE_SEND_COMPLETE_ID,
STATE_SEND_PACKETS // send packets or debug strings
};
State state = STATE_SEND_NOTHING;
int8_t config_state = Config_device_tag;
/**
* Each packet sent to the phone has an incrementing count
*/
@@ -60,7 +59,7 @@ class PhoneAPI
// Call this when the client drops the connection, resets the state to STATE_SEND_NOTHING
// Unregisters our observer. A closed connection **can** be reopened by calling init again.
virtual void close();
/**
* Handle a ToRadio protobuf
* @return true true if a packet was queued for sending (so that caller can yield)
@@ -82,6 +81,8 @@ class PhoneAPI
bool isConnected() { return state != STATE_SEND_NOTHING; }
void setInitialState() { state = STATE_SEND_MY_INFO; }
/// emit a debugging log character, FIXME - implement
void debugOut(char c) { }
+6 -3
View File
@@ -75,12 +75,15 @@ template <class T> class ProtobufModule : protected SinglePortModule
T scratch;
T *decoded = NULL;
if (mp.which_payloadVariant == MeshPacket_decoded_tag && mp.decoded.portnum == ourPortNum) {
if (mp.which_payload_variant == MeshPacket_decoded_tag && mp.decoded.portnum == ourPortNum) {
memset(&scratch, 0, sizeof(scratch));
if (pb_decode_from_bytes(p.payload.bytes, p.payload.size, fields, &scratch))
if (pb_decode_from_bytes(p.payload.bytes, p.payload.size, fields, &scratch)) {
decoded = &scratch;
else
} else {
DEBUG_MSG("Error decoding protobuf module!\n");
// if we can't decode it, nobody can process it!
return ProcessMessage::STOP;
}
}
return handleReceivedProtobuf(mp, decoded) ? ProcessMessage::STOP : ProcessMessage::CONTINUE;
+26 -23
View File
@@ -70,19 +70,23 @@ bool RF95Interface::init()
int res = lora->begin(getFreq(), bw, sf, cr, syncWord, power, currentLimit, preambleLength);
DEBUG_MSG("RF95 init result %d\n", res);
DEBUG_MSG("Frequency set to %f\n", getFreq());
DEBUG_MSG("Bandwidth set to %f\n", bw);
DEBUG_MSG("Power output set to %d\n", power);
// current limit was removed from module' ctor
// override default value (60 mA)
res = lora->setCurrentLimit(currentLimit);
DEBUG_MSG("Current limit set to %f\n", currentLimit);
DEBUG_MSG("Current limit set result %d\n", res);
if (res == ERR_NONE)
res = lora->setCRC(SX126X_LORA_CRC_ON);
if (res == RADIOLIB_ERR_NONE)
res = lora->setCRC(RADIOLIB_SX126X_LORA_CRC_ON);
if (res == ERR_NONE)
if (res == RADIOLIB_ERR_NONE)
startReceive(); // start receiving
return res == ERR_NONE;
return res == RADIOLIB_ERR_NONE;
}
void INTERRUPT_ATTR RF95Interface::disableInterrupt()
@@ -99,39 +103,39 @@ bool RF95Interface::reconfigure()
// configure publicly accessible settings
int err = lora->setSpreadingFactor(sf);
if (err != ERR_NONE)
RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
if (err != RADIOLIB_ERR_NONE)
RECORD_CRITICALERROR(CriticalErrorCode_INVALID_RADIO_SETTING);
err = lora->setBandwidth(bw);
if (err != ERR_NONE)
RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
if (err != RADIOLIB_ERR_NONE)
RECORD_CRITICALERROR(CriticalErrorCode_INVALID_RADIO_SETTING);
err = lora->setCodingRate(cr);
if (err != ERR_NONE)
RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
if (err != RADIOLIB_ERR_NONE)
RECORD_CRITICALERROR(CriticalErrorCode_INVALID_RADIO_SETTING);
err = lora->setSyncWord(syncWord);
assert(err == ERR_NONE);
assert(err == RADIOLIB_ERR_NONE);
err = lora->setCurrentLimit(currentLimit);
assert(err == ERR_NONE);
assert(err == RADIOLIB_ERR_NONE);
err = lora->setPreambleLength(preambleLength);
assert(err == ERR_NONE);
assert(err == RADIOLIB_ERR_NONE);
err = lora->setFrequency(getFreq());
if (err != ERR_NONE)
RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
if (err != RADIOLIB_ERR_NONE)
RECORD_CRITICALERROR(CriticalErrorCode_INVALID_RADIO_SETTING);
if (power > MAX_POWER) // This chip has lower power limits than some
power = MAX_POWER;
err = lora->setOutputPower(power);
if (err != ERR_NONE)
RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
if (err != RADIOLIB_ERR_NONE)
RECORD_CRITICALERROR(CriticalErrorCode_INVALID_RADIO_SETTING);
startReceive(); // restart receiving
return ERR_NONE;
return RADIOLIB_ERR_NONE;
}
/**
@@ -147,7 +151,7 @@ void RF95Interface::addReceiveMetadata(MeshPacket *mp)
void RF95Interface::setStandby()
{
int err = lora->standby();
assert(err == ERR_NONE);
assert(err == RADIOLIB_ERR_NONE);
isReceiving = false; // If we were receiving, not any more
disableInterrupt();
@@ -168,7 +172,7 @@ void RF95Interface::startReceive()
setTransmitEnable(false);
setStandby();
int err = lora->startReceive();
assert(err == ERR_NONE);
assert(err == RADIOLIB_ERR_NONE);
isReceiving = true;
@@ -184,12 +188,11 @@ bool RF95Interface::isChannelActive()
setStandby(); // needed for smooth transition
result = lora->scanChannel();
if (result == PREAMBLE_DETECTED) {
if (result == RADIOLIB_PREAMBLE_DETECTED) {
// DEBUG_MSG("Channel is busy!\n");
return true;
}
assert(result != ERR_WRONG_MODEM);
assert(result != RADIOLIB_ERR_WRONG_MODEM);
// DEBUG_MSG("Channel is free!\n");
return false;
+3 -2
View File
@@ -13,8 +13,9 @@ class RF95Interface : public RadioLibInterface
public:
RF95Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, SPIClass &spi);
bool isIRQPending() override { return lora->getPendingIRQ(); }
//TODO: Verify that this irq flag works with RFM95 / SX1276 radios the way it used to
bool isIRQPending() override { return lora->getIRQFlags() & RADIOLIB_SX127X_MASK_IRQ_FLAG_VALID_HEADER; }
/// Initialise the Driver transport hardware and software.
/// Make sure the Driver is properly configured before calling init().
+66 -65
View File
@@ -27,7 +27,7 @@ const RegionInfo regions[] = {
/*
https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf
*/
RDEF(EU433, 433.0f, 434.0f, 10, 0, 12, true, false),
RDEF(EU_433, 433.0f, 434.0f, 10, 0, 12, true, false),
/*
https://www.thethingsnetwork.org/docs/lorawan/duty-cycle/
@@ -35,8 +35,15 @@ const RegionInfo regions[] = {
https://www.legislation.gov.uk/uksi/1999/930/schedule/6/part/III/made/data.xht?view=snippet&wrap=true
audio_permitted = false per regulation
Special Note:
The link above describes LoRaWAN's band plan, stating a power limit of 16 dBm. This is their own suggested specification,
we do not need to follow it. The European Union regulations clearly state that the power limit for this frequency range is 500 mW, or 27 dBm.
It also states that we can use interference avoidance and spectrum access techniques to avoid a duty cycle.
(Please refer to section 4.21 in the following document)
https://ec.europa.eu/growth/tools-databases/tris/index.cfm/ro/search/?trisaction=search.detail&year=2021&num=528&dLang=EN
*/
RDEF(EU868, 869.4f, 869.65f, 10, 0, 16, false, false),
RDEF(EU_868, 869.4f, 869.65f, 10, 0, 27, false, false),
/*
https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf
@@ -81,7 +88,7 @@ const RegionInfo regions[] = {
https://rrf.rsm.govt.nz/smart-web/smart/page/-smart/domain/licence/LicenceSummary.wdk?id=219752
https://iotalliance.org.nz/wp-content/uploads/sites/4/2019/05/IoT-Spectrum-in-NZ-Briefing-Paper.pdf
*/
RDEF(NZ865, 864.0f, 868.0f, 100, 0, 0, true, false),
RDEF(NZ_865, 864.0f, 868.0f, 100, 0, 0, true, false),
/*
https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf
@@ -91,7 +98,7 @@ const RegionInfo regions[] = {
/*
This needs to be last. Same as US.
*/
RDEF(Unset, 902.0f, 928.0f, 100, 0, 30, true, false)
RDEF(UNSET, 902.0f, 928.0f, 100, 0, 30, true, false)
};
@@ -100,7 +107,7 @@ const RegionInfo *myRegion;
void initRegion()
{
const RegionInfo *r = regions;
for (; r->code != Config_LoRaConfig_RegionCode_Unset && r->code != config.lora.region; r++)
for (; r->code != Config_LoRaConfig_RegionCode_UNSET && r->code != config.lora.region; r++)
;
myRegion = r;
DEBUG_MSG("Wanted region %d, using %s\n", config.lora.region, r->name);
@@ -150,7 +157,7 @@ uint32_t RadioInterface::getPacketTime(uint32_t pl)
uint32_t RadioInterface::getPacketTime(MeshPacket *p)
{
assert(p->which_payloadVariant == MeshPacket_encrypted_tag); // It should have already been encoded by now
assert(p->which_payload_variant == MeshPacket_encrypted_tag); // It should have already been encoded by now
uint32_t pl = p->encrypted.size + sizeof(PacketHeader);
return getPacketTime(pl);
@@ -159,61 +166,50 @@ uint32_t RadioInterface::getPacketTime(MeshPacket *p)
/** The delay to use for retransmitting dropped packets */
uint32_t RadioInterface::getRetransmissionMsec(const MeshPacket *p)
{
assert(shortPacketMsec); // Better be non zero
assert(slotTimeMsec); // Better be non zero
static uint8_t bytes[MAX_RHPACKETLEN];
size_t numbytes = pb_encode_to_bytes(bytes, sizeof(bytes), Data_fields, &p->decoded);
uint32_t packetAirtime = getPacketTime(numbytes + sizeof(PacketHeader));
uint32_t tCADmsec = 2 * (1 << sf) / bw; // duration of CAD is roughly 2 symbols according to SX127x datasheet
/* Make sure enough time has elapsed for this packet to be sent and an ACK is received.
* Right now we have to wait until another node floods the same packet, as that is our implicit ACK.
* TODO: Revise when want_ack will be used (right now it is always set to 0 afterwards).
*/
return 2*packetAirtime + 2*MIN_TX_WAIT_MSEC + shortPacketMsec + shortPacketMsec*2 + PROCESSING_TIME_MSEC + 2*tCADmsec;
// Make sure enough time has elapsed for this packet to be sent and an ACK is received.
// DEBUG_MSG("Waiting for flooding message with airtime %d and slotTime is %d\n", packetAirtime, slotTimeMsec);
float channelUtil = airTime->channelUtilizationPercent();
uint8_t CWsize = map(channelUtil, 0, 100, CWmin, CWmax);
// Assuming we pick max. of CWsize and there will be a receiver with SNR at half the range
return 2*packetAirtime + (pow(2, CWsize) + pow(2, int((CWmax+CWmin)/2))) * slotTimeMsec + PROCESSING_TIME_MSEC;
}
/** The delay to use when we want to send something but the ether is busy */
/** The delay to use when we want to send something */
uint32_t RadioInterface::getTxDelayMsec()
{
/** At the low end we want to pick a delay large enough that anyone who just completed sending (some other node)
* has had enough time to switch their radio back into receive mode.
*/
const uint32_t MIN_TX_WAIT_MSEC = 100;
/**
* At the high end, this value is used to spread node attempts across time so when they are replying to a packet
* they don't both check that the airwaves are clear at the same moment. As long as they are off by some amount
* one of the two will be first to start transmitting and the other will see that. I bet 500ms is more than enough
* to guarantee this.
*/
// const uint32_t MAX_TX_WAIT_MSEC = 2000; // stress test would still fail occasionally with 1000
return random((MIN_TX_WAIT_MSEC), (MIN_TX_WAIT_MSEC + shortPacketMsec));
/** We wait a random multiple of 'slotTimes' (see definition in header file) in order to avoid collisions.
The pool to take a random multiple from is the contention window (CW), which size depends on the
current channel utilization. */
float channelUtil = airTime->channelUtilizationPercent();
uint8_t CWsize = map(channelUtil, 0, 100, CWmin, CWmax);
// DEBUG_MSG("Current channel utilization is %f so setting CWsize to %d\n", channelUtil, CWsize);
return random(0, pow(2, CWsize)) * slotTimeMsec;
}
/** The delay to use when we want to send something but the ether is busy */
/** The delay to use when we want to flood a message */
uint32_t RadioInterface::getTxDelayMsecWeighted(float snr)
{
/** At the low end we want to pick a delay large enough that anyone who just completed sending (some other node)
* has had enough time to switch their radio back into receive mode.
*/
const uint32_t MIN_TX_WAIT_MSEC = 100;
// The minimum value for a LoRa SNR
const uint32_t SNR_MIN = -20;
// The maximum value for a LoRa SNR
const uint32_t SNR_MAX = 15;
// high SNR = Long Delay
// low SNR = Short Delay
// high SNR = large CW size (Long Delay)
// low SNR = small CW size (Short Delay)
uint32_t delay = 0;
if (config.device.role == Config_DeviceConfig_Role_Router ||
config.device.role == Config_DeviceConfig_Role_RouterClient) {
delay = map(snr, SNR_MIN, SNR_MAX, MIN_TX_WAIT_MSEC, (MIN_TX_WAIT_MSEC + (shortPacketMsec / 2)));
uint8_t CWsize = map(snr, SNR_MIN, SNR_MAX, CWmin, CWmax);
// DEBUG_MSG("rx_snr of %f so setting CWsize to:%d\n", snr, CWsize);
if (config.device.role == Config_DeviceConfig_Role_ROUTER ||
config.device.role == Config_DeviceConfig_Role_ROUTER_CLIENT) {
delay = random(0, 2*CWsize) * slotTimeMsec;
DEBUG_MSG("rx_snr found in packet. As a router, setting tx delay:%d\n", delay);
} else {
delay = map(snr, SNR_MIN, SNR_MAX, MIN_TX_WAIT_MSEC + (shortPacketMsec / 2), (MIN_TX_WAIT_MSEC + shortPacketMsec * 2));
delay = random(0, pow(2, CWsize)) * slotTimeMsec;
DEBUG_MSG("rx_snr found in packet. Setting tx delay:%d\n", delay);
}
@@ -224,7 +220,7 @@ void printPacket(const char *prefix, const MeshPacket *p)
{
DEBUG_MSG("%s (id=0x%08x Fr0x%02x To0x%02x, WantAck%d, HopLim%d Ch0x%x", prefix, p->id, p->from & 0xff, p->to & 0xff,
p->want_ack, p->hop_limit, p->channel);
if (p->which_payloadVariant == MeshPacket_decoded_tag) {
if (p->which_payload_variant == MeshPacket_decoded_tag) {
auto &s = p->decoded;
DEBUG_MSG(" Portnum=%d", s.portnum);
@@ -358,40 +354,39 @@ void RadioInterface::applyModemConfig()
// Set up default configuration
// No Sync Words in LORA mode
Config_LoRaConfig &loraConfig = config.lora;
auto channelSettings = channels.getPrimary();
if (loraConfig.spread_factor == 0) {
switch (loraConfig.modem_preset) {
case Config_LoRaConfig_ModemPreset_ShortFast:
case Config_LoRaConfig_ModemPreset_SHORT_FAST:
bw = 250;
cr = 8;
sf = 7;
break;
case Config_LoRaConfig_ModemPreset_ShortSlow:
case Config_LoRaConfig_ModemPreset_SHORT_SLOW:
bw = 250;
cr = 8;
sf = 8;
break;
case Config_LoRaConfig_ModemPreset_MidFast:
case Config_LoRaConfig_ModemPreset_MEDIUM_FAST:
bw = 250;
cr = 8;
sf = 9;
break;
case Config_LoRaConfig_ModemPreset_MidSlow:
case Config_LoRaConfig_ModemPreset_MEDIUM_SLOW:
bw = 250;
cr = 8;
sf = 10;
break;
case Config_LoRaConfig_ModemPreset_LongFast:
case Config_LoRaConfig_ModemPreset_LONG_FAST:
bw = 250;
cr = 8;
sf = 11;
break;
case Config_LoRaConfig_ModemPreset_LongSlow:
case Config_LoRaConfig_ModemPreset_LONG_SLOW:
bw = 125;
cr = 8;
sf = 12;
break;
case Config_LoRaConfig_ModemPreset_VLongSlow:
case Config_LoRaConfig_ModemPreset_VERY_LONG_SLOW:
bw = 31.25;
cr = 8;
sf = 12;
@@ -411,27 +406,39 @@ void RadioInterface::applyModemConfig()
}
power = loraConfig.tx_power;
shortPacketMsec = getPacketTime(sizeof(PacketHeader));
assert(myRegion); // Should have been found in init
if ((power == 0) || (power > myRegion->powerLimit))
power = myRegion->powerLimit;
if (power == 0)
power = 17; // Default to default power if we don't have a valid power
// Set final tx_power back onto config
loraConfig.tx_power = power;
// Calculate the number of channels
uint32_t numChannels = floor((myRegion->freqEnd - myRegion->freqStart) / (myRegion->spacing + (bw / 1000)));
// If user has manually specified a channel num, then use that, otherwise generate one by hashing the name
const char *channelName = channels.getName(channels.getPrimaryIndex());
int channel_num = channelSettings.channel_num ? channelSettings.channel_num - 1 : hash(channelName) % numChannels;
float freq = myRegion->freqStart + ((((myRegion->freqEnd - myRegion->freqStart) / numChannels) / 2) * channel_num);
int channel_num = loraConfig.channel_num ? loraConfig.channel_num - 1 : hash(channelName) % numChannels;
// Old frequency selection formula
// float freq = myRegion->freqStart + ((((myRegion->freqEnd - myRegion->freqStart) / numChannels) / 2) * channel_num);
// New frequency selection formula
float freq = myRegion->freqStart + (bw / 2000) + ( channel_num * (bw / 1000));
saveChannelNum(channel_num);
saveFreq(freq);
saveFreq(freq + config.lora.frequency_offset);
DEBUG_MSG("Set radio: name=%s, config=%u, ch=%d, power=%d\n", channelName, loraConfig.modem_preset, channel_num, power);
DEBUG_MSG("Radio myRegion->freqStart / myRegion->freqEnd: %f -> %f (%f mhz)\n", myRegion->freqStart, myRegion->freqEnd,
myRegion->freqEnd - myRegion->freqStart);
DEBUG_MSG("Set radio: region=%s, name=%s, config=%u, ch=%d, power=%d\n", myRegion->name, channelName, loraConfig.modem_preset, channel_num, power);
DEBUG_MSG("Radio myRegion->freqStart / myRegion->freqEnd: %f -> %f (%f mhz)\n", myRegion->freqStart, myRegion->freqEnd, myRegion->freqEnd - myRegion->freqStart);
DEBUG_MSG("Radio myRegion->numChannels: %d\n", numChannels);
DEBUG_MSG("Radio channel_num: %d\n", channel_num);
DEBUG_MSG("Radio frequency: %f\n", getFreq());
DEBUG_MSG("Short packet time: %u msec\n", shortPacketMsec);
DEBUG_MSG("Slot time: %u msec\n", slotTimeMsec);
}
/**
@@ -453,12 +460,6 @@ void RadioInterface::limitPower()
DEBUG_MSG("Set radio: final power level=%d\n", power);
}
ErrorCode SimRadio::send(MeshPacket *p)
{
DEBUG_MSG("SimRadio.send\n");
packetPool.release(p);
return ERRNO_OK;
}
void RadioInterface::deliverToReceiver(MeshPacket *p)
{
@@ -474,7 +475,7 @@ size_t RadioInterface::beginSending(MeshPacket *p)
assert(!sendingPacket);
// DEBUG_MSG("sending queued packet on mesh (txGood=%d,rxGood=%d,rxBad=%d)\n", rf95.txGood(), rf95.rxGood(), rf95.rxBad());
assert(p->which_payloadVariant == MeshPacket_encrypted_tag); // It should have already been encoded by now
assert(p->which_payload_variant == MeshPacket_encrypted_tag); // It should have already been encoded by now
lastTxStart = millis();
+10 -11
View File
@@ -52,8 +52,6 @@ class RadioInterface
CallbackObserver<RadioInterface, void *> notifyDeepSleepObserver =
CallbackObserver<RadioInterface, void *>(this, &RadioInterface::notifyDeepSleepCb);
/// Number of msecs we expect our shortest actual packet to be over the wire (used in retry timeout calcs)
uint32_t shortPacketMsec;
protected:
bool disabled = false;
@@ -61,10 +59,16 @@ class RadioInterface
float bw = 125;
uint8_t sf = 9;
uint8_t cr = 7;
/** Slottime is the minimum time to wait, consisting of:
- CAD duration (maximum of SX126x and SX127x);
- roundtrip air propagation time (assuming max. 30km between nodes);
- Tx/Rx turnaround time (maximum of SX126x and SX127x);
- MAC processing time (measured on T-beam) */
uint32_t slotTimeMsec = 8.5 * pow(2, sf)/bw + 0.2 + 0.4 + 7;
uint16_t preambleLength = 32; // 8 is default, but we use longer to increase the amount of sleep time when receiving
const uint32_t MIN_TX_WAIT_MSEC = 100; // minimum time to wait before transmitting after sensing the channel in ms
const uint32_t PROCESSING_TIME_MSEC = 4500; // time to construct, process and construct a packet again (empirically determined)
const uint8_t CWmin = 2; // minimum CWsize
const uint8_t CWmax = 8; // maximum CWsize
MeshPacket *sendingPacket = NULL; // The packet we are currently sending
uint32_t lastTxStart = 0L;
@@ -128,10 +132,10 @@ class RadioInterface
/** The delay to use for retransmitting dropped packets */
uint32_t getRetransmissionMsec(const MeshPacket *p);
/** The delay to use when we want to send something but the ether is busy */
/** The delay to use when we want to send something */
uint32_t getTxDelayMsec();
/** The delay to use when we want to send something but the ether is busy. Use a weighted scale based on SNR */
/** The delay to use when we want to flood a message. Use a weighted scale based on SNR */
uint32_t getTxDelayMsecWeighted(float snr);
@@ -208,11 +212,6 @@ class RadioInterface
}
};
class SimRadio : public RadioInterface
{
public:
virtual ErrorCode send(MeshPacket *p) override;
};
/// Debug printing for packets
void printPacket(const char *prefix, const MeshPacket *p);
+45 -27
View File
@@ -11,6 +11,8 @@
// FIXME, we default to 4MHz SPI, SPI mode 0, check if the datasheet says it can really do that
static SPISettings spiSettings(4000000, MSBFIRST, SPI_MODE0);
#ifdef ARCH_PORTDUINO
void LockingModule::SPItransfer(uint8_t cmd, uint8_t reg, uint8_t *dataOut, uint8_t *dataIn, uint8_t numBytes)
{
concurrency::LockGuard g(spiLock);
@@ -18,14 +20,36 @@ void LockingModule::SPItransfer(uint8_t cmd, uint8_t reg, uint8_t *dataOut, uint
Module::SPItransfer(cmd, reg, dataOut, dataIn, numBytes);
}
#else
void LockingModule::SPIbeginTransaction()
{
spiLock->lock();
Module::SPIbeginTransaction();
}
void LockingModule::SPIendTransaction()
{
spiLock->unlock();
Module::SPIendTransaction();
}
#endif
RadioLibInterface::RadioLibInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy,
SPIClass &spi, PhysicalLayer *_iface)
: NotifiedWorkerThread("RadioIf"), module(cs, irq, rst, busy, spi, spiSettings), iface(_iface)
{
instance = this;
#if defined(ARCH_STM32WL) && defined(USE_SX1262)
module.setCb_digitalWrite(stm32wl_emulate_digitalWrite);
module.setCb_digitalRead(stm32wl_emulate_digitalRead);
#endif
}
#ifndef NO_ESP32
#ifdef ARCH_ESP32
// ESP32 doesn't use that flag
#define YIELD_FROM_ISR(x) portYIELD_FROM_ISR()
#else
@@ -75,8 +99,8 @@ bool RadioLibInterface::canSendImmediately()
// TX IRQ from the radio, the radio is probably broken.
if (busyTx && (millis() - lastTxStart > 60000)) {
DEBUG_MSG("Hardware Failure! busyTx for more than 60s\n");
RECORD_CRITICALERROR(CriticalErrorCode_TransmitFailed);
#ifndef NO_ESP32
RECORD_CRITICALERROR(CriticalErrorCode_TRANSMIT_FAILED);
#ifdef ARCH_ESP32
if (busyTx && (millis() - lastTxStart > 65000)) // After 5s more, reboot
ESP.restart();
#endif
@@ -96,18 +120,18 @@ ErrorCode RadioLibInterface::send(MeshPacket *p)
#ifndef DISABLE_WELCOME_UNSET
if (config.lora.region != Config_LoRaConfig_RegionCode_Unset) {
if (disabled || config.lora.tx_disabled) {
if (config.lora.region != Config_LoRaConfig_RegionCode_UNSET) {
if (disabled || !config.lora.tx_enabled) {
if (config.lora.region != Config_LoRaConfig_RegionCode_Unset) {
if (disabled || config.lora.tx_disabled) {
DEBUG_MSG("send - lora_tx_disabled\n");
if (config.lora.region != Config_LoRaConfig_RegionCode_UNSET) {
if (disabled || !config.lora.tx_enabled) {
DEBUG_MSG("send - !config.lora.tx_enabled\n");
packetPool.release(p);
return ERRNO_DISABLED;
}
} else {
DEBUG_MSG("send - lora_tx_disabled because RegionCode_Unset\n");
DEBUG_MSG("send - lora tx disable because RegionCode_Unset\n");
packetPool.release(p);
return ERRNO_DISABLED;
}
@@ -116,8 +140,8 @@ ErrorCode RadioLibInterface::send(MeshPacket *p)
#else
if (disabled || config.lora.tx_disabled) {
DEBUG_MSG("send - lora_tx_disabled\n");
if (disabled || !config.lora.tx_enabled) {
DEBUG_MSG("send - !config.lora.tx_enabled\n");
packetPool.release(p);
return ERRNO_DISABLED;
}
@@ -170,17 +194,11 @@ ErrorCode RadioLibInterface::send(MeshPacket *p)
}
/** radio helper thread callback.
We never immediately transmit after any operation (either rx or tx). Instead we should start receiving and
wait a random delay of 100ms to 100ms+shortPacketMsec to make sure we are not stomping on someone else. The 100ms delay
at the beginning ensures all possible listeners have had time to finish processing the previous packet and now have their
radio in RX state. The up to 100ms+shortPacketMsec random delay gives a chance for all possible senders to have high odds
of detecting that someone else started transmitting first and then they will wait until that packet finishes.
NOTE: the large flood rebroadcast delay might still be needed even with this approach. Because we might not be able to
hear other transmitters that we are potentially stomping on. Requires further thought.
FIXME, the MIN_TX_WAIT_MSEC and MAX_TX_WAIT_MSEC values should be tuned via logic analyzer later.
We never immediately transmit after any operation (either Rx or Tx). Instead we should wait a random multiple of
'slotTimes' (see definition in RadioInterface.h) taken from a contention window (CW) to lower the chance of collision.
The CW size is determined by setTransmitDelay() and depends either on the current channel utilization or SNR in case
of a flooding message. After this, we perform channel activity detection (CAD) and reset the transmit delay if it is
currently active.
*/
void RadioLibInterface::onNotify(uint32_t notification)
{
@@ -308,7 +326,7 @@ ErrorCode RadioLibInterface::send(MeshPacket *p)
xmitMsec = getPacketTime(length);
int state = iface->readData(radiobuf, length);
if (state != ERR_NONE) {
if (state != RADIOLIB_ERR_NONE) {
DEBUG_MSG("ignoring received packet due to error=%d\n", state);
rxBad++;
@@ -344,7 +362,7 @@ ErrorCode RadioLibInterface::send(MeshPacket *p)
addReceiveMetadata(mp);
mp->which_payloadVariant = MeshPacket_encrypted_tag; // Mark that the payload is still encrypted at this point
mp->which_payload_variant = MeshPacket_encrypted_tag; // Mark that the payload is still encrypted at this point
assert(((uint32_t)payloadLen) <= sizeof(mp->encrypted.bytes));
memcpy(mp->encrypted.bytes, payload, payloadLen);
mp->encrypted.size = payloadLen;
@@ -363,7 +381,7 @@ ErrorCode RadioLibInterface::send(MeshPacket *p)
void RadioLibInterface::startSend(MeshPacket * txp)
{
printPacket("Starting low level send", txp);
if (disabled || config.lora.tx_disabled) {
if (disabled || !config.lora.tx_enabled) {
DEBUG_MSG("startSend is dropping tx packet because we are disabled\n");
packetPool.release(txp);
} else {
@@ -374,8 +392,8 @@ ErrorCode RadioLibInterface::send(MeshPacket *p)
size_t numbytes = beginSending(txp);
int res = iface->startTransmit(radiobuf, numbytes);
if (res != ERR_NONE) {
RECORD_CRITICALERROR(CriticalErrorCode_RadioSpiBug);
if (res != RADIOLIB_ERR_NONE) {
RECORD_CRITICALERROR(CriticalErrorCode_RADIO_SPI_BUG);
// This send failed, but make sure to 'complete' it properly
completeSending();
+7 -15
View File
@@ -40,21 +40,13 @@ class LockingModule : public Module
: Module(cs, irq, rst, gpio, spi, spiSettings)
{
}
/*!
\brief SPI single transfer method.
\param cmd SPI access command (read/write/burst/...).
\param reg Address of SPI register to transfer to/from.
\param dataOut Data that will be transfered from master to slave.
\param dataIn Data that was transfered from slave to master.
\param numBytes Number of bytes to transfer.
*/
virtual void SPItransfer(uint8_t cmd, uint8_t reg, uint8_t *dataOut, uint8_t *dataIn, uint8_t numBytes) override;
#ifdef ARCH_PORTDUINO
void SPItransfer(uint8_t cmd, uint8_t reg, uint8_t *dataOut, uint8_t *dataIn, uint8_t numBytes) override;
#else
void SPIbeginTransaction() override;
void SPIendTransaction() override;
#endif
};
class RadioLibInterface : public RadioInterface, protected concurrency::NotifiedWorkerThread
+3 -3
View File
@@ -15,7 +15,7 @@ int16_t RadioLibRF95::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_
{
// execute common part
int16_t state = SX127x::begin(RF95_CHIP_VERSION, syncWord, preambleLength);
if (state != ERR_NONE)
if (state != RADIOLIB_ERR_NONE)
state = SX127x::begin(RF95_ALT_VERSION, syncWord, preambleLength);
RADIOLIB_ASSERT(state);
@@ -30,7 +30,7 @@ int16_t RadioLibRF95::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_
RADIOLIB_ASSERT(state);
#ifdef RF95_TCXO
state = _mod->SPIsetRegValue(SX127X_REG_TCXO, 0x10 | _mod->SPIgetRegValue(SX127X_REG_TCXO));
state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_TCXO, 0x10 | _mod->SPIgetRegValue(RADIOLIB_SX127X_REG_TCXO));
RADIOLIB_ASSERT(state);
#endif
@@ -72,7 +72,7 @@ int16_t RadioLibRF95::setFrequency(float freq)
bool RadioLibRF95::isReceiving()
{
// 0x0b == Look for header info valid, signal synchronized or signal detected
uint8_t reg = readReg(SX127X_REG_MODEM_STAT);
uint8_t reg = readReg(RADIOLIB_SX127X_REG_MODEM_STAT);
// Serial.printf("reg %x\n", reg);
return (reg & (RH_RF95_MODEM_STATUS_SIGNAL_DETECTED | RH_RF95_MODEM_STATUS_SIGNAL_SYNCHRONIZED |
RH_RF95_MODEM_STATUS_HEADER_INFO_VALID)) != 0;
+1 -1
View File
@@ -43,7 +43,7 @@ class RadioLibRF95: public SX1278 {
\returns \ref status_codes
*/
int16_t begin(float freq = 915.0, float bw = 125.0, uint8_t sf = 9, uint8_t cr = 7, uint8_t syncWord = SX127X_SYNC_WORD, int8_t power = 17, uint16_t preambleLength = 8, uint8_t gain = 0);
int16_t begin(float freq = 915.0, float bw = 125.0, uint8_t sf = 9, uint8_t cr = 7, uint8_t syncWord = RADIOLIB_SX127X_SYNC_WORD, int8_t power = 17, uint16_t preambleLength = 8, uint8_t gain = 0);
// configuration methods

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