Compare commits

...

169 Commits

Author SHA1 Message Date
Jm Casler
19c1f9fa59 Bump to 1.2.53 2022-01-27 18:41:29 -08:00
Jm Casler
266d6ad205 Proto regen for .53 2022-01-27 17:52:03 -08:00
Jm Casler
66cd824437 Merge pull request #1162 from mkinney/remote_hw
gpio read and write work as expected
2022-01-27 17:49:23 -08:00
mkinney
e2db4f6927 Merge branch 'master' into remote_hw 2022-01-27 17:40:29 -08:00
Jm Casler
56fb141ed0 updating proto submodule to latest 2022-01-27 17:40:00 -08:00
Mike Kinney
e8e209be25 gpio read and write work as expected 2022-01-28 00:11:16 +00:00
mkinney
c278a0e299 Merge pull request #1149 from caveman99/caveman99-patch-1
accept one or more environment definitions
2022-01-27 11:39:43 -08:00
mkinney
fbc25c3a13 Merge branch 'master' into caveman99-patch-1 2022-01-27 11:09:57 -08:00
mkinney
b7f04f4c91 Merge pull request #1159 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-01-27 11:09:46 -08:00
mkinney
d5377a0f19 Merge branch 'master' into create-pull-request/patch 2022-01-27 10:40:01 -08:00
Jm Casler
dafc1092aa Merge pull request #1158 from meshtastic/thebentern-patch-2
Ignore markdown and yml for continuous integration
2022-01-27 10:37:09 -08:00
Jm Casler
477b666998 Merge branch 'master' into thebentern-patch-2 2022-01-27 10:37:04 -08:00
Jm Casler
dbcd720391 Merge pull request #1154 from osmanovv/patch-1
Fix MISO/MOSI pins for DIY v1.1
2022-01-27 10:36:38 -08:00
Ben Meadors
59c2bcd978 Merge branch 'master' into thebentern-patch-2 2022-01-27 12:33:55 -06:00
mkinney
aea6675e64 [create-pull-request] automated change 2022-01-27 18:32:55 +00:00
mkinney
8bff696bef Merge branch 'master' into patch-1 2022-01-27 10:28:21 -08:00
mkinney
da0ec09bf4 Merge pull request #1157 from meshtastic/thebentern-patch-1
Create pr instead of commit
2022-01-27 10:28:03 -08:00
Ben Meadors
2c99020037 Ignore markdown and yml for continuous integration 2022-01-27 11:59:08 -06:00
Ben Meadors
14419cbd02 Create pr instead of commit 2022-01-27 11:54:32 -06:00
Ben Meadors
1bfa6839e2 Use correct path to mesh (#1155) 2022-01-27 08:57:49 -06:00
Ben Meadors
a61676504f Attempt to only update proto (#1153) 2022-01-27 07:51:51 -06:00
Vladislav Osmanov
f4d3de086a Fix MISO/MOSI pins for DIY v1.1 2022-01-27 16:49:55 +03:00
Thomas Göttgens
af249da1a3 accept one or more environment definitions
This is a non breaking change. Up till now you could either specify ONE board to check or run with default settings hich would check a sensible set. With this change you can provide a space-separated list of boards to check, this facilitates parallel CI executions better.
2022-01-27 09:18:31 +01:00
Jm Casler
7613c7bf83 Merge pull request #1148 from mc-hamster/master
position plugin - only send if channel utilization is <50 percent
2022-01-26 22:40:52 -08:00
Jm Casler
e4608e0a10 position plugin - only send if channel utilization is <50 percent 2022-01-26 22:32:33 -08:00
Jm Casler
d26549c7c2 Merge pull request #1147 from mc-hamster/master
rangeTestPlugin - only send if channelUtilization is less than 25%
2022-01-26 22:20:35 -08:00
Jm Casler
697d52b9bd rangeTestPlugin - only send if channelUtilization is less than 25% 2022-01-26 22:20:13 -08:00
Ben Meadors
7a9450b250 Only update protos (#1145) 2022-01-26 16:17:30 -06:00
Jm Casler
6d372743f5 updating proto submodule to latest 2022-01-26 13:35:46 -08:00
mkinney
c2b309195d Merge pull request #1144 from meshtastic/update-protos-action
Update protobufs and regenerate classes action
2022-01-26 13:24:58 -08:00
Ben Meadors
3c7670186a Update protobufs and regenerate classes 2022-01-26 14:25:30 -06:00
Ben Meadors
b51be320dd BME680 support (#1142) 2022-01-25 14:22:48 -06:00
Thomas Göttgens
409ad9c2c3 Split platformio.ini into one file for each board, only leaving platform definitions and a handful of stale (?) boards around.. (#1141) 2022-01-25 08:56:16 -06:00
mkinney
eaa5252cdb Merge pull request #1138 from mkinney/fix_some_cpp_warnings
Fix some cpp warnings
2022-01-24 15:34:58 -08:00
Mike Kinney
3d718f45d5 fail the build if we have any cppcheck warnings 2022-01-24 21:35:24 +00:00
mkinney
a8dab94087 Merge branch 'master' into fix_some_cpp_warnings 2022-01-24 13:27:33 -08:00
mkinney
5a348da0e9 Merge pull request #1139 from caveman99/master
use the new version of Screen lib when building
2022-01-24 13:27:18 -08:00
Thomas Göttgens
115b835b83 Merge branch 'master' into master 2022-01-24 21:57:54 +01:00
Thomas Göttgens
9df42799ff Tryfix: Local replica for build problem (#1)
* Tryfix: Local replica for build problem

* Update platformio.ini

* use the real repo again
2022-01-24 21:56:31 +01:00
mkinney
e1d3c01199 Merge branch 'master' into fix_some_cpp_warnings 2022-01-24 12:52:21 -08:00
mkinney
bdcc0f252b Merge pull request #1140 from costonisp/master
added a new variant heltec_2.1
2022-01-24 12:44:49 -08:00
Mike Kinney
437aa1e9af make check a different job on ci 2022-01-24 20:04:31 +00:00
Mike Kinney
6883bc7afc fix more warnings; add to CI; suppress some warnings 2022-01-24 19:58:07 +00:00
co sto
a2eef895bd Create variant.h 2022-01-24 20:40:28 +01:00
co sto
64671c8ce7 Delete variants/heltev_v2.1 directory 2022-01-24 20:38:51 +01:00
Thomas Göttgens
252a27174e New checkout for library 2022-01-24 20:28:16 +01:00
Mike Kinney
7c362af3de more warning fixes 2022-01-24 18:39:17 +00:00
co sto
c6b851a2e6 Update variant.h 2022-01-24 19:01:23 +01:00
co sto
ec4346aba3 Update variant.h 2022-01-24 18:59:09 +01:00
co sto
791186a264 Create variant.h 2022-01-24 18:58:32 +01:00
co sto
ab947f06aa Delete .heltec_v2.1 2022-01-24 18:55:51 +01:00
co sto
cfa0ceb604 Create .heltec_v2.1 2022-01-24 18:55:26 +01:00
co sto
c7686ad57e Delete variant.h 2022-01-24 18:46:35 +01:00
co sto
8732b7cb4d Add files via upload 2022-01-24 18:45:51 +01:00
co sto
fe9dcbb316 Delete heltec_v2.1 2022-01-24 18:40:15 +01:00
co sto
38d1a381e6 Create heltec_v2.1 2022-01-24 18:35:25 +01:00
co sto
0b2f1d5675 Update platformio.ini 2022-01-24 18:33:31 +01:00
Mike Kinney
caaa235c5d more cppcheck warnings fixes 2022-01-24 17:24:40 +00:00
Thomas Göttgens
9a0126cde1 use the new version of Screen lib when building 2022-01-24 17:37:33 +01:00
co sto
39d0c0fd8f Merge branch 'meshtastic:master' into master 2022-01-24 14:00:33 +01:00
mkinney
be0b9979bc Merge pull request #3 from meshtastic/master
refresh branch from master
2022-01-23 23:02:02 -08:00
Mike Kinney
b3210f6c2c fix some cppcheck warnings 2022-01-24 07:00:14 +00:00
Jm Casler
2357240d84 Merge pull request #1136 from osmanovv/diy-v11
Meshtastic DIY v1.1 new schematic
2022-01-23 20:43:00 -08:00
co sto
c2f0048931 Merge branch 'meshtastic:master' into master 2022-01-24 00:14:42 +01:00
Vladislav Osmanov
d1ba314065 Meshtastic DIY v1.1 new schematic 2022-01-23 23:44:58 +03:00
Jm Casler
8a79ede285 Merge pull request #1135 from mc-hamster/master
Protos regened for reply and tapback
2022-01-23 09:31:26 -08:00
Jm Casler
c8ecd6ac8e Protos regened for reply and tapback 2022-01-23 09:30:44 -08:00
Jm Casler
13226adb2a updating proto submodule to latest 2022-01-23 09:10:33 -08:00
Ben Meadors
e706aae41d Added NRF/RAK support for env plugin (#1133)
* Added NRF/RAK support for env plugin

* Added Environmental mixin to platform io
2022-01-23 10:05:39 -06:00
co sto
91ad0df11c Update variant.h 2022-01-23 17:04:55 +01:00
co sto
976627d974 Merge branch 'meshtastic:master' into master 2022-01-23 14:20:29 +01:00
Jm Casler
6830f9861a Merge pull request #1132 from mc-hamster/master
set the routerMessage buffer to Constants_DATA_PAYLOAD_LEN
2022-01-23 02:14:55 -08:00
Jm Casler
2db307fc8d Merge branch 'meshtastic:master' into master 2022-01-23 01:05:36 -08:00
Jm Casler
7fae43e1a5 Merge branch 'master' of https://github.com/mc-hamster/Meshtastic-device 2022-01-23 01:05:09 -08:00
Jm Casler
8b60226497 set the routerMessage buffer to Constants_DATA_PAYLOAD_LEN 2022-01-23 01:05:07 -08:00
Jm Casler
ab8083dec4 Merge pull request #1131 from mc-hamster/master
Fixes PIO code inspector
2022-01-23 01:01:50 -08:00
Jm Casler
a561713a48 Merge branch 'meshtastic:master' into master 2022-01-23 00:29:54 -08:00
Jm Casler
00f3996cee Merge branch 'master' of https://github.com/mc-hamster/Meshtastic-device 2022-01-23 00:29:24 -08:00
Jm Casler
9e4e79c5d7 Fixes PIO code inspector 2022-01-23 00:29:16 -08:00
Ben Meadors
61e1b8d859 Set lastMeasurementPacket as one we're sending (#1130) 2022-01-22 19:24:47 -06:00
mkinney
165e8e8cba Merge pull request #1127 from mkinney/add_docker
initial dockerfile and notes
2022-01-22 14:02:19 -08:00
mkinney
635fbcf0d5 Merge branch 'master' into add_docker 2022-01-22 13:34:29 -08:00
mkinney
815222ad80 Merge pull request #1128 from osmanovv/diy-rfm95
RFM95/SX127x support in DIY
2022-01-22 13:34:17 -08:00
mkinney
64a9f15b1c Merge branch 'master' into add_docker 2022-01-22 13:16:20 -08:00
Ben Meadors
abcdf39b20 Merge branch 'master' into diy-rfm95 2022-01-22 15:09:57 -06:00
Ben Meadors
16ee75313a BME280 support for environment and screen re-org (#1129) 2022-01-22 15:09:17 -06:00
Vladislav Osmanov
bfd9938507 RFM95/SX127x support in DIY 2022-01-22 16:13:52 +03:00
Mike Kinney
01f5f1b5ba initial dockerfile and notes 2022-01-22 00:01:32 -08:00
Ben Meadors
b6706c7ac1 Admin message shutdown feature (#1124)
* Shutdown via proto admin message
2022-01-21 15:03:26 -06:00
Thomas Göttgens
7723b30951 Custom_ArialMT_Plain_10 not used anywhere (#1122) 2022-01-21 09:53:57 -06:00
Ben Meadors
6d34151590 Admin message shutdown protobufs (#1119)
* Updated protos for admin message shutdown protobufs
2022-01-20 21:43:15 -06:00
co sto
2230cbbe2a Correction for wrong battery display on tlora_v2_1_16 board (#1120)
* Update variant.h
2022-01-20 20:47:30 -06:00
co sto
b49ba55658 Merge branch 'master' into master 2022-01-21 02:37:39 +01:00
co sto
0864154157 Update platformio.ini 2022-01-21 02:26:59 +01:00
co sto
c4f64b1592 Update variant.h 2022-01-21 02:09:25 +01:00
co sto
001d054924 Update platformio.ini 2022-01-21 02:07:29 +01:00
mkinney
5e590a4a5e Merge pull request #1118 from meshtastic/mkinney-patch-1
Update README.md
2022-01-20 10:57:17 -08:00
mkinney
22a2fe2cb4 Update README.md
add github downloads badge
2022-01-20 10:16:18 -08:00
mkinney
f047ae6792 Update README.md
add ci badge
2022-01-20 10:04:43 -08:00
Ben Meadors
e1ef495071 Add tlora-v2-1-1.6 to default envs for consistency (#1117) 2022-01-20 08:34:03 -06:00
Jm Casler
209c6253a6 updating proto submodule to latest 2022-01-19 18:18:55 -08:00
mkinney
1acabb9d35 Merge pull request #1110 from prampec/master
Temporary fix on canned messages total length.
2022-01-19 16:14:56 -08:00
mkinney
420495cb2d Merge branch 'master' into master 2022-01-19 15:45:58 -08:00
Ben Meadors
9309824874 RAK / NRF shutdown functionality on user button long press (#1113) 2022-01-19 17:10:02 -06:00
Balázs Kelemen
4fc443e760 Merge branch 'meshtastic:master' into master 2022-01-19 17:22:34 +01:00
Balazs Kelemen
53399f06e5 Canned message plugin status fix. 2022-01-19 09:55:06 +01:00
Ben Meadors
4e3fda87a1 Initial configuration.h -> variants refactor (#1104)
* Initial configuration to variants refactor
2022-01-18 18:35:42 -06:00
Balazs Kelemen
1ff3b3326c Temporary fix on canned messages total length. 2022-01-18 23:15:54 +01:00
mkinney
9f0ddda6ca Merge pull request #1107 from mkinney/fix_warning
change name of define because MAX_BLOCKSIZE is already taken
2022-01-17 23:14:26 -08:00
mkinney
8e3d30bd7f Merge branch 'master' into fix_warning 2022-01-17 22:44:01 -08:00
mkinney
6ca3186bff Merge pull request #1106 from mkinney/add_more_env_sensors
add DHT22
2022-01-17 22:17:48 -08:00
Mike Kinney
68fadfe26c change name of define because MAX_BLOCKSIZE is already taken 2022-01-18 06:13:43 +00:00
Jm Casler
92bcdb5e53 updating proto submodule to latest 2022-01-17 09:23:29 -08:00
Jm Casler
04b1948ee9 Merge pull request #1105 from prampec/master
CannedMessagePlugin typo fix.
2022-01-16 22:46:57 -08:00
Mike Kinney
6fdc16017a revert the cheking for esptool 2022-01-17 02:31:25 +00:00
Mike Kinney
7f759d6bb5 Merge remote-tracking branch 'prampec/master' into add_more_env_sensors 2022-01-17 00:03:14 +00:00
Mike Kinney
1f227797c1 updated file after updating protobufs 2022-01-16 23:54:10 +00:00
Mike Kinney
ab87c0a9ee updating proto 2022-01-16 23:49:18 +00:00
Mike Kinney
6d960918e2 minor change to re-trigger ci 2022-01-16 15:22:17 -08:00
Mike Kinney
5797e32461 add support for other 2 sensors 2022-01-16 15:16:03 -08:00
Mike Kinney
41da6c3b99 add DHT22 2022-01-16 15:06:34 -08:00
Balazs Kelemen
fe3a352511 CannedMessagePlugin typo fix. 2022-01-16 23:18:40 +01:00
Jm Casler
b53f4214bc Merge pull request #1099 from mc-hamster/master
AirTime - fix bug in array shifter
2022-01-15 15:28:39 -08:00
Jm Casler
b6b1bcc5ad Merge branch 'meshtastic:master' into master 2022-01-15 15:27:45 -08:00
Jm Casler
91117ca7c6 AirTime - fix bug in array shifter 2022-01-15 15:27:25 -08:00
Jm Casler
2d8e55a34e Merge pull request #1098 from mc-hamster/master
Airtime - calculate ms in a hour in preprocessor
2022-01-15 12:24:50 -08:00
Jm Casler
3a7292d3d0 Merge branch 'meshtastic:master' into master 2022-01-15 12:24:31 -08:00
Jm Casler
3fea1c4e5f Merge branch 'master' of https://github.com/mc-hamster/Meshtastic-device 2022-01-15 12:24:17 -08:00
Jm Casler
c2435470c1 Airtime - calculate ms in a hour in preprocessor 2022-01-15 12:24:16 -08:00
Jm Casler
1c993c10a1 Merge pull request #1097 from mc-hamster/master
airtime - reuse some functions
2022-01-15 11:20:33 -08:00
Jm Casler
0a62ce23af Merge branch 'master' into master 2022-01-15 11:20:21 -08:00
Jm Casler
38efb8b3ad Merge branch 'master' of https://github.com/mc-hamster/Meshtastic-device 2022-01-15 11:19:52 -08:00
Jm Casler
9ee7f5e0bd airtime - reuse some functions 2022-01-15 11:19:50 -08:00
Jm Casler
c798e1a2da Merge pull request #1096 from mc-hamster/master
Airtime - removed debug message
2022-01-15 09:51:46 -08:00
Jm Casler
7eb4713422 Merge branch 'meshtastic:master' into master 2022-01-15 09:51:10 -08:00
Jm Casler
a9ed26fdbc Merge pull request #1090 from prampec/CannedMessagePlugin
Canned message plugin
2022-01-15 09:50:39 -08:00
Jm Casler
a7451b6abe Airtime - removed debug message 2022-01-15 09:50:10 -08:00
Jm Casler
e61db642bc Merge pull request #1095 from mc-hamster/master
Add airtime tx calculation as a 1hr rolling window
2022-01-15 09:45:12 -08:00
Jm Casler
25a540c28b Add airtime tx calculation as a 1hr rolling window 2022-01-15 09:44:29 -08:00
Jm Casler
1993b8f8a6 updating proto submodule to latest 2022-01-15 09:34:11 -08:00
Jm Casler
38dd5612fd Merge branch 'master' into CannedMessagePlugin 2022-01-15 09:20:10 -08:00
Jm Casler
8a63c6f3a3 Merge pull request #1094 from mc-hamster/master
Fix borked airtime report in /json/reports
2022-01-15 08:25:46 -08:00
Jm Casler
778d13dee7 Merge branch 'meshtastic:master' into master 2022-01-15 08:25:11 -08:00
Jm Casler
2fd0d2baff Fixed borked airtime report in /json/reports
For: https://github.com/meshtastic/Meshtastic-device/issues/1086
2022-01-15 08:24:39 -08:00
Jm Casler
399792803a Merge pull request #1092 from mkinney/add_quotes_in_device_install
add quotes around PYTHON; add check for esptool
2022-01-15 07:49:30 -08:00
Mike Kinney
8a6bbcb985 add quotes around PYTHON; add check for esptool 2022-01-14 10:40:18 -08:00
Jm Casler
419349e13e Merge branch 'master' into CannedMessagePlugin 2022-01-13 17:31:12 -08:00
Jm Casler
6b0770fdd5 Merge pull request #1088 from markbirss/master
Fix SSD1306 OLED pinout on TLORA_V1_3
2022-01-13 17:22:21 -08:00
Jm Casler
ee2b05da78 Merge branch 'master' into master 2022-01-13 16:56:06 -08:00
Jm Casler
d900847bab updating proto submodule to latest 2022-01-13 16:55:20 -08:00
Ben Meadors
8b56ebd566 Merge branch 'master' into CannedMessagePlugin 2022-01-13 13:20:02 -06:00
Balazs Kelemen
a1f80f024e CannedMessagePlugin merge fix 2022-01-13 14:19:55 +01:00
Balazs Kelemen
41de8a1309 Relocate 'input' folder. 2022-01-13 14:17:21 +01:00
Balazs Kelemen
33f08364e4 Reset plugin in case of inactivity. 2022-01-13 14:17:21 +01:00
Balazs Kelemen
c5b95ed3c0 Screen update event. 2022-01-13 14:17:21 +01:00
Balazs Kelemen
f7c8cabdfe Screen drawing routine goes to Plugin. 2022-01-13 14:17:20 +01:00
Balazs Kelemen
0f1c424731 Rotary get rid of duplicate methods. 2022-01-13 14:17:20 +01:00
Balazs Kelemen
3fa00f603b Make all variables configurable. 2022-01-13 14:17:16 +01:00
Balazs Kelemen
f5004a66a1 Introduce InputBroker 2022-01-13 14:15:53 +01:00
Balazs Kelemen
b832b82ec6 Use init() instead of constructor. 2022-01-13 14:15:53 +01:00
Balazs Kelemen
fbd5b8b721 Canned message bugfixes. 2022-01-13 14:15:53 +01:00
Balazs Kelemen
772dfe39dc Combine rotary with canned messages. 2022-01-13 14:15:53 +01:00
Balazs Kelemen
c7e62142e9 RotaryEncoderInterruptBase 2022-01-13 14:15:53 +01:00
Balazs Kelemen
6eb2b33124 Fix rotary glitch. 2022-01-13 14:15:53 +01:00
Balazs Kelemen
b3ddf16d64 Display sending state. 2022-01-13 14:15:53 +01:00
Balazs Kelemen
4a29aef19e Show previous and next message in list. 2022-01-13 14:15:53 +01:00
Balazs Kelemen
7b8849493f Adding screen frame 2022-01-13 14:15:53 +01:00
Balazs Kelemen
2b588f1567 CannedMessagePlugin initial commit 2022-01-13 14:15:53 +01:00
Mark Trevor Birss
975f7c0332 Fix SSD1306 OLED pinout on TLORA_V1_3
The V1.3 board OLED pinout changed from V1
Now on pin SDA(21) and SCL(22) not SDA(4) and SCL(15)

LILYGO Product Page
http://www.lilygo.cn/prod_view.aspx?TypeId=50060&Id=1253&FId=t3:50060:3

Product Pin
https://ae01.alicdn.com/kf/H098cb5d5159841b398fcfd4ebf705725W.jpg
2022-01-13 10:28:02 +02:00
154 changed files with 2558 additions and 1718 deletions

View File

@@ -3,19 +3,56 @@ on:
# Triggers the workflow on push or pull request events but only for the master branch # Triggers the workflow on push or pull request events but only for the master branch
push: push:
branches: [ master ] branches: [ master ]
paths-ignore:
- '**.md'
- '**.yml'
pull_request: pull_request:
branches: [ master ] branches: [ master ]
paths-ignore:
- '**.md'
- '**.yml'
jobs: jobs:
# setup:
# runs-on: ubuntu-latest ci-check:
# steps: runs-on: ubuntu-latest
steps:
# - name: Startup
# run: echo "No action setup currently needed, skipping..." - name: Checkout code
uses: actions/checkout@v2
with:
submodules: 'recursive'
- 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: ci-build:
# needs: setup
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
@@ -36,10 +73,6 @@ jobs:
path: ~/.cache/pip path: ~/.cache/pip
key: ${{ runner.os }}-pip key: ${{ runner.os }}-pip
#- name: Install linux apt packages
# run: |
# sudo apt-get install -y libgpiod-dev
- name: Upgrade python tools - name: Upgrade python tools
# We actually want to run this every time # We actually want to run this every time
# if: steps.cache-pip.outputs.cache-hit != 'true' # if: steps.cache-pip.outputs.cache-hit != 'true'

View File

@@ -1,4 +1,4 @@
name: "Update protobufs" name: "Update protobufs and regenerate classes"
on: workflow_dispatch on: workflow_dispatch
jobs: jobs:
@@ -11,14 +11,23 @@ jobs:
with: with:
submodules: true submodules: true
- name: Update Submodule - name: Update submodule
run: | run: |
git pull --recurse-submodules git submodule update --remote proto
git submodule update --remote --recursive
- name: Commit update - name: Download nanopb
run: | run: |
git config --global user.name 'github-actions' wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.4-linux-x86.tar.gz
git config --global user.email 'bot@noreply.github.com' tar xvzf nanopb-0.4.4-linux-x86.tar.gz
git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }} mv nanopb-0.4.4-linux-x86 nanopb-0.4.4
git add proto
git commit -m "Update protobuf submodule" && git push || echo "No changes to commit" - name: Re-generate protocol buffers
run: |
./bin/regen-protos.sh
- name: Create pull request
uses: peter-evans/create-pull-request@v3
with:
add-paths: |
proto
src/mesh

3
.gitignore vendored
View File

@@ -26,3 +26,6 @@ __pycache__
*.swp *.swp
*.swo *.swo
*~ *~
venv/
release/

16
Dockerfile Normal file
View File

@@ -0,0 +1,16 @@
FROM ubuntu
MAINTAINER Kevin Hester <kevinh@geeksville.com>
RUN apt-get update
RUN DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get -y install wget python3 g++ zip python3-venv git vim
RUN wget https://raw.githubusercontent.com/platformio/platformio-core-installer/master/get-platformio.py -O get-platformio.py; chmod +x get-platformio.py
RUN python3 get-platformio.py
RUN git clone https://github.com/meshtastic/Meshtastic-device.git
RUN cd Meshtastic-device; git submodule update --init --recursive
# only build the simulator
RUN sed -i 's/^BOARDS_ESP32.*/BOARDS_ESP32=""/' Meshtastic-device/bin/build-all.sh
RUN sed -i 's/^BOARDS_NRF52.*/BOARDS_NRF52=""/' Meshtastic-device/bin/build-all.sh
RUN sed -i 's/echo "Building SPIFFS.*/exit/' Meshtastic-device/bin/build-all.sh
RUN . ~/.platformio/penv/bin/activate; cd Meshtastic-device; ./bin/build-all.sh
CMD ["/Meshtastic-device/release/latest/bins/universal/meshtasticd_linux_amd64"]

View File

@@ -1,5 +1,8 @@
# Meshtastic-device # Meshtastic-device
[![Open in Visual Studio Code](https://open.vscode.dev/badges/open-in-vscode.svg)](https://open.vscode.dev/meshtastic/Meshtastic-device) [![Open in Visual Studio Code](https://open.vscode.dev/badges/open-in-vscode.svg)](https://open.vscode.dev/meshtastic/Meshtastic-device)
[![Continuous Integration](https://github.com/meshtastic/Meshtastic-device/actions/workflows/main.yml/badge.svg)](https://github.com/meshtastic/Meshtastic-device/actions/workflows/main.yml)
![GitHub all releases](https://img.shields.io/github/downloads/meshtastic/meshtastic-device/total)
## This repository contains the device firmware used in the [Meshtastic](https://meshtastic.org) project. ## This repository contains the device firmware used in the [Meshtastic](https://meshtastic.org) project.
Update Instructions Update Instructions

26
bin/check-all.sh Executable file
View File

@@ -0,0 +1,26 @@
#!/usr/bin/env bash
# Note: This is a prototype for how we could add static code analysis to the CI.
set -e
VERSION=`bin/buildinfo.py long`
# The shell vars the build tool expects to find
export APP_VERSION=$VERSION
if [[ $# -gt 0 ]]; then
# can override which environment by passing arg
BOARDS="-e $@"
else
BOARDS="tlora-v2 tlora-v1 tlora_v1_3 tlora-v2-1-1.6 tbeam heltec-v1 heltec-v2.0 heltec-v2.1 tbeam0.7 meshtastic-diy-v1 rak4631_5005 rak4631_19003 t-echo"
fi
#echo "BOARDS:${BOARDS}"
CHECK=""
for BOARD in $BOARDS; do
CHECK="${CHECK} -e ${BOARD}"
done
pio check --flags "-DAPP_VERSION=${APP_VERSION} --suppressions-list=suppressions.txt" $CHECK --skip-packages --pattern="src/" --fail-on-defect=low --fail-on-defect=medium --fail-on-defect=high

View File

@@ -11,7 +11,7 @@ Usage: $(basename $0) [-h] [-p ESPTOOL_PORT] [-P PYTHON] [-f FILENAME|FILENAME]
Flash image file to device, but first erasing and writing system information" Flash image file to device, but first erasing and writing system information"
-h Display this help and exit -h Display this help and exit
-p ESPTOOL_PORT Set the environment variable for ESPTOOL_PORT. If not set, ESPTOOL iterates all ports (Dangerrous). -p ESPTOOL_PORT Set the environment variable for ESPTOOL_PORT. If not set, ESPTOOL iterates all ports (Dangerous).
-P PYTHON Specify alternate python interpreter to use to invoke esptool. (Default: "$PYTHON") -P PYTHON Specify alternate python interpreter to use to invoke esptool. (Default: "$PYTHON")
-f FILENAME The .bin file to flash. Custom to your device type and region. -f FILENAME The .bin file to flash. Custom to your device type and region.
EOF EOF
@@ -46,10 +46,10 @@ shift "$((OPTIND-1))"
if [ -f "${FILENAME}" ]; then if [ -f "${FILENAME}" ]; then
echo "Trying to flash ${FILENAME}, but first erasing and writing system information" echo "Trying to flash ${FILENAME}, but first erasing and writing system information"
$PYTHON -m esptool erase_flash "$PYTHON" -m esptool erase_flash
$PYTHON -m esptool write_flash 0x1000 system-info.bin "$PYTHON" -m esptool write_flash 0x1000 system-info.bin
$PYTHON -m esptool write_flash 0x00390000 spiffs-*.bin "$PYTHON" -m esptool write_flash 0x00390000 spiffs-*.bin
$PYTHON -m esptool write_flash 0x10000 ${FILENAME} "$PYTHON" -m esptool write_flash 0x10000 ${FILENAME}
else else
echo "Invalid file: ${FILENAME}" echo "Invalid file: ${FILENAME}"
show_help show_help

17
docker.txt Normal file
View File

@@ -0,0 +1,17 @@
To build:
docker build -t meshtastic/device .
To run:
docker run --rm -p 4403:4403 meshtastic/device
or, to get a shell on the docker image:
docker run -it meshtastic/device bash
To use python cli against it:
meshtastic --info --host localhost
To stop:
# run this to get id
docker ps
# tip: you can just use the first few characters of the id in the next command
docker kill <id>

View File

@@ -11,12 +11,14 @@
[platformio] [platformio]
default_envs = tbeam default_envs = tbeam
;default_envs = tbeam0.7 ;default_envs = tbeam0.7
;default_envs = heltec-v2.0
;default_envs = heltec-v1 ;default_envs = heltec-v1
;default_envs = heltec-v2.0
;default_envs = heltec-v2.1
;default_envs = tlora-v1 ;default_envs = tlora-v1
;default_envs = tlora-v1 ;default_envs = tlora-v1
;default_envs = tlora_v1_3 ;default_envs = tlora_v1_3
;default_envs = tlora-v2 ;default_envs = tlora-v2
;default_envs = tlora-v2-1-1.6
;default_envs = lora-relay-v1 # nrf board ;default_envs = lora-relay-v1 # nrf board
;default_envs = t-echo ;default_envs = t-echo
;default_envs = nrf52840dk-geeksville ;default_envs = nrf52840dk-geeksville
@@ -24,6 +26,11 @@ default_envs = tbeam
;default_envs = rak4631 ;default_envs = rak4631
;default_envs = rak4630 ;default_envs = rak4630
;default_envs = meshtastic-diy-v1 ;default_envs = meshtastic-diy-v1
;default_envs = meshtastic-diy-v1.1
; board specific config can be moved to the respective 'variants' file.
; See https://docs.platformio.org/en/latest/projectconf/section_platformio.html#extra-configs
extra_configs = variants/*/platformio.ini
[common] [common]
; common is not currently used ; common is not currently used
@@ -70,7 +77,7 @@ debug_tool = jlink
; monitor adapter_khz 10000 ; monitor adapter_khz 10000
lib_deps = lib_deps =
https://github.com/meshtastic/esp8266-oled-ssd1306.git#35d796226b853b0c0ff818b2f1aa3d35e7296a96 ; ESP8266_SSD1306 https://github.com/meshtastic/esp8266-oled-ssd1306.git#d90231dedbb2f52bd7a32fb8ed8edec52cf4a8cb ; ESP8266_SSD1306
https://github.com/meshtastic/OneButton.git#3bcba9492d01e2a8a86f46700ab16f96dd2cf1f5 ; OneButton library for non-blocking button debounce https://github.com/meshtastic/OneButton.git#3bcba9492d01e2a8a86f46700ab16f96dd2cf1f5 ; OneButton library for non-blocking button debounce
1202 ; CRC32, explicitly needed because dependency is missing in the ble ota update lib 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/arduino-fsm.git
@@ -82,8 +89,12 @@ lib_deps =
SPI SPI
https://github.com/geeksville/ArduinoThread.git#72921ac222eed6f526ba1682023cee290d9aa1b3 https://github.com/geeksville/ArduinoThread.git#72921ac222eed6f526ba1682023cee290d9aa1b3
PubSubClient PubSubClient
; Common settings for conventional (non Portduino) Ardino targets ; Used for the code analysis in PIO Home / Inspect
check_tool = cppcheck
check_skip_packages = yes
; Common settings for conventional (non Portduino) Arduino targets
[arduino_base] [arduino_base]
framework = arduino framework = arduino
@@ -96,6 +107,16 @@ build_flags = ${env.build_flags} -Os
src_filter = ${env.src_filter} -<portduino/> src_filter = ${env.src_filter} -<portduino/>
; Common libs for environmental measurements (not included in native / portduino)
[environmental]
lib_deps =
adafruit/DHT sensor library@^1.4.1
adafruit/Adafruit Unified Sensor@^1.1.4
paulstoffregen/OneWire@^2.3.5
robtillaart/DS18B20@^0.1.11
adafruit/Adafruit BME280 Library@^2.2.2
adafruit/Adafruit BME680 Library@^2.0.1
; Common settings for ESP targes, mixin with extends = esp32_base ; Common settings for ESP targes, mixin with extends = esp32_base
[esp32_base] [esp32_base]
extends = arduino_base extends = arduino_base
@@ -114,11 +135,8 @@ build_flags =
-DAXP_DEBUG_PORT=Serial -DAXP_DEBUG_PORT=Serial
lib_deps = lib_deps =
${arduino_base.lib_deps} ${arduino_base.lib_deps}
${environmental.lib_deps}
https://github.com/meshtastic/esp32_https_server.git https://github.com/meshtastic/esp32_https_server.git
adafruit/DHT sensor library@^1.4.1
adafruit/Adafruit Unified Sensor@^1.1.4
paulstoffregen/OneWire@^2.3.5
robtillaart/DS18B20@^0.1.11
h2zero/NimBLE-Arduino@1.3.4 h2zero/NimBLE-Arduino@1.3.4
tobozo/ESP32-targz@^1.1.4 tobozo/ESP32-targz@^1.1.4
arduino-libraries/NTPClient#531eff39d9fbc831f3d03f706a161739203fbe2a arduino-libraries/NTPClient#531eff39d9fbc831f3d03f706a161739203fbe2a
@@ -150,78 +168,6 @@ board_build.partitions = partition-table.csv
; -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG ; -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
; The 1.0 release of the TBEAM board
[env:tbeam]
extends = esp32_base
board = ttgo-t-beam
lib_deps =
${esp32_base.lib_deps}
build_flags =
${esp32_base.build_flags} -D TBEAM_V10
; The original TBEAM board without the AXP power chip and a few other changes
; Note: I've heard reports this didn't work. Disabled until someone with a 0.7 can test and debug.
[env:tbeam0.7]
extends = esp32_base
board = ttgo-t-beam
build_flags =
${esp32_base.build_flags} -D TBEAM_V07
[env:heltec-v1]
;build_type = debug ; to make it possible to step through our jtag debugger
extends = esp32_base
board = heltec_wifi_lora_32
build_flags =
${esp32_base.build_flags} -D HELTEC_V1
[env:heltec-v2.0]
;build_type = debug ; to make it possible to step through our jtag debugger
extends = esp32_base
board = heltec_wifi_lora_32_V2
build_flags =
${esp32_base.build_flags} -D HELTEC_V2_0
[env:heltec-v2.1]
;build_type = debug ; to make it possible to step through our jtag debugger
extends = esp32_base
board = heltec_wifi_lora_32_V2
build_flags =
${esp32_base.build_flags} -D HELTEC_V2_1
[env:tlora-v1]
extends = esp32_base
board = ttgo-lora32-v1
build_flags =
${esp32_base.build_flags} -D TLORA_V1
; note: the platformio definition for lora32-v2 seems stale, it is missing a pins_arduino.h file, therefore I don't think it works
[env:tlora_v1_3]
extends = esp32_base
board = ttgo-lora32-v1
build_flags =
${esp32_base.build_flags} -D TLORA_V1_3
[env:tlora-v2]
extends = esp32_base
board = ttgo-lora32-v1
build_flags =
${esp32_base.build_flags} -D TLORA_V2
[env:tlora-v2-1-1.6]
extends = esp32_base
board = ttgo-lora32-v1
build_flags =
${esp32_base.build_flags} -D TLORA_V2_1_16
; Meshtastic DIY v1 by Nano VHF Schematic based on ESP32-WROOM-32 (38 pins) devkit & EBYTE E22 SX1262/SX1268 module
[env:meshtastic-diy-v1]
extends = esp32_base
board = esp32doit-devkit-v1
build_flags =
${esp32_base.build_flags}
-D DIY_V1
-D EBYTE_E22
; The Heltec Cubecell plus ; The Heltec Cubecell plus
; IMPORTANT NOTE: This target doesn't yet work and probably won't ever work. I'm keeping it around for now. ; IMPORTANT NOTE: This target doesn't yet work and probably won't ever work. I'm keeping it around for now.
; For more details see my post in the forum. ; For more details see my post in the forum.
@@ -291,42 +237,17 @@ extends = nrf52_base
build_flags = ${nrf52_base.build_flags} build_flags = ${nrf52_base.build_flags}
lib_deps = lib_deps =
${arduino_base.lib_deps} ${arduino_base.lib_deps}
${environmental.lib_deps}
Adafruit nRFCrypto Adafruit nRFCrypto
# Adafruit TinyUSB Arduino # Adafruit TinyUSB Arduino
# add Adafruit nRFCrypto platform IO automated scan is broken # add Adafruit nRFCrypto platform IO automated scan is broken
[env:lora_isp4520]
extends = nrf52_base
board = lora_isp4520
# add our variants files to the include and src paths
build_flags = ${nrf52_base.build_flags} -Ivariants/lora_isp4520
# No screen and GPS on the board. We still need RTC.cpp for the RTC clock.
src_filter = ${nrf52_base.src_filter} +<../variants/lora_isp4520> -<graphics> -<gps> +<gps/GPS.cpp> +<gps/RTC.cpp>
lib_ignore = ${nrf52_base.lib_ignore}
ESP8266_SSD1306
SparkFun Ublox Arduino Library
AXP202X_Library
TinyGPSPlus
upload_protocol = jlink
monitor_port = /dev/ttyUSB0
; The NRF52840-dk development board ; The NRF52840-dk development board
; Note: By default no lora device is created for this build - it uses a simulated interface ; Note: By default no lora device is created for this build - it uses a simulated interface
[env:nrf52840dk] [env:nrf52840dk]
extends = nrf52840_base extends = nrf52840_base
board = nrf52840_dk board = nrf52840_dk
; The NRF52840-dk development board, but @geeksville's board - which has a busted oscilliator
[env:nrf52840dk-geeksville]
extends = nrf52840_base
board = nrf52840_dk_modified
# add our variants files to the include and src paths
build_flags = ${nrf52_base.build_flags} -Ivariants/pca10056-rc-clock
src_filter = ${nrf52_base.src_filter} +<../variants/pca10056-rc-clock>
; Note: By default no lora device is created for this build - it uses a simulated interface ; Note: By default no lora device is created for this build - it uses a simulated interface
[env:feather_nrf52832] [env:feather_nrf52832]
extends = nrf52_base extends = nrf52_base
@@ -343,161 +264,3 @@ monitor_speed = 115200
# For experimenting with RAM sizes # For experimenting with RAM sizes
# board_build.ldscript = linker/nrf52840_s140_sim832.ld # board_build.ldscript = linker/nrf52840_s140_sim832.ld
; The very slick RAK wireless RAK 4631 / 4630 board
[env:rak4631_5005]
extends = nrf52840_base
board = wiscore_rak4631
# add our variants files to the include and src paths
# define build flags for the TFT_eSPI library
build_flags = ${nrf52840_base.build_flags} -Ivariants/WisCore_RAK4631_Board -D RAK_BASE_5005
src_filter = ${nrf52_base.src_filter} +<../variants/WisCore_RAK4631_Board>
debug_tool = jlink
[env:rak4631_19003]
extends = nrf52840_base
board = wiscore_rak4631
# add our variants files to the include and src paths
# define build flags for the TFT_eSPI library
build_flags = ${nrf52840_base.build_flags} -Ivariants/WisCore_RAK4631_Board -D RAK_BASE_19003
src_filter = ${nrf52_base.src_filter} +<../variants/WisCore_RAK4631_Board>
debug_tool = jlink
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
;upload_protocol = jlink
; Note, this board is not yet supported! It will not work without futher development.
; THIS IS UNTESTED (I don't have this board), but other developers can use it as a starting point
[env:rak4600]
extends = nrf52_base
board = wiscore_rak4600
# add our variants files to the include and src paths
# define build flags for the TFT_eSPI library
build_flags = ${nrf52_base.build_flags} -Ivariants/WisCore_RAK4600_Board
src_filter = ${nrf52_base.src_filter} +<../variants/WisCore_RAK4600_Board>
lib_deps =
${arduino_base.lib_deps}
; The PPR board
[env:ppr]
extends = nrf52_base
board = ppr
lib_deps =
${arduino_base.lib_deps}
UC1701
; The PPR board
[env:ppr1]
extends = nrf52_base
board = ppr1
build_flags = ${nrf52_base.build_flags} -Ivariants/ppr1
src_filter = ${nrf52_base.src_filter} +<../variants/ppr1>
lib_deps =
${arduino_base.lib_deps}
; First prototype eink/nrf52840/sx1262 device
[env:t-echo]
extends = nrf52840_base
board = t-echo
debug_tool = jlink
upload_protocol = jlink
# add our variants files to the include and src paths
# define build flags for the TFT_eSPI library - NOTE: WE NOT LONGER USE TFT_eSPI, it was for an earlier version of the TTGO eink screens
# -DBUSY_PIN=3 -DRST_PIN=2 -DDC_PIN=28 -DCS_PIN=30
# add -DCFG_SYSVIEW if you want to use the Segger systemview tool for OS profiling.
build_flags = ${nrf52840_base.build_flags} -Ivariants/t-echo
src_filter = ${nrf52_base.src_filter} +<../variants/t-echo>
lib_deps =
${nrf52840_base.lib_deps}
https://github.com/geeksville/GxEPD2.git
adafruit/Adafruit BusIO
;upload_protocol = fs
; First prototype eink/nrf52840/sx1262 device (removed from build because didn't ship in quantity)
;[env:eink0.1]
;extends = nrf52840_base
;board = eink0.1
;# add our variants files to the include and src paths
;# define build flags for the TFT_eSPI library
;build_flags = ${nrf52_base.build_flags} -Ivariants/eink0.1
; -DBUSY_PIN=3 -DRST_PIN=2 -DDC_PIN=28 -DCS_PIN=30
;src_filter = ${nrf52_base.src_filter} +<../variants/eink0.1>
;lib_deps =
; ${nrf52840_base.lib_deps}
; https://github.com/geeksville/EPD_Libraries.git
; TFT_eSPI
; The https://github.com/BigCorvus/SX1262-LoRa-BLE-Relay board by @BigCorvus
[env:lora-relay-v1]
extends = nrf52840_base
board = lora-relay-v1
# add our variants files to the include and src paths
# define build flags for the TFT_eSPI library
build_flags = ${nrf52840_base.build_flags} -Ivariants/lora_relay_v1
-DUSER_SETUP_LOADED
-DTFT_WIDTH=80
-DTFT_HEIGHT=160
-DST7735_GREENTAB160x80
-DST7735_DRIVER
-DTFT_CS=ST7735_CS
-DTFT_DC=ST7735_RS
-DTFT_RST=ST7735_RESET
-DSPI_FREQUENCY=27000000
src_filter = ${nrf52_base.src_filter} +<../variants/lora_relay_v1>
lib_deps =
${nrf52840_base.lib_deps}
SparkFun BQ27441 LiPo Fuel Gauge Arduino Library
TFT_eSPI
; The https://github.com/BigCorvus/LoRa-BLE-Relay-v2 board by @BigCorvus
[env:lora-relay-v2]
extends = nrf52840_base
board = lora-relay-v2
# add our variants files to the include and src paths
# define build flags for the TFT_eSPI library
build_flags = ${nrf52840_base.build_flags} -Ivariants/lora_relay_v2
-DUSER_SETUP_LOADED
-DTFT_WIDTH=80
-DTFT_HEIGHT=160
-DST7735_GREENTAB160x80
-DST7735_DRIVER
-DTFT_CS=ST7735_CS
-DTFT_DC=ST7735_RS
-DTFT_RST=ST7735_RESET
-DSPI_FREQUENCY=27000000
-DTFT_WR=ST7735_SDA
-DTFT_SCLK=ST7735_SCK
src_filter = ${nrf52_base.src_filter} +<../variants/lora_relay_v2>
lib_deps =
${nrf52840_base.lib_deps}
SparkFun BQ27441 LiPo Fuel Gauge Arduino Library
TFT_eSPI
; The Portduino based sim environment on top of any host OS, all hardware will be simulated
[env:native]
platform = https://github.com/geeksville/platform-native.git
src_filter = ${env.src_filter} -<esp32/> -<nimble/> -<nrf52/> -<mesh/http/> -<plugins/esp32>
build_flags = ${arduino_base.build_flags} -O0
framework = arduino
board = cross_platform
lib_deps =
${arduino_base.lib_deps}
rweather/Crypto
; The Portduino based sim environment on top of a linux OS and touching linux hardware devices
[env:linux]
platform = https://github.com/geeksville/platform-native.git
src_filter = ${env.src_filter} -<esp32/> -<nimble/> -<nrf52/> -<mesh/http/> -<plugins/esp32>
build_flags = ${arduino_base.build_flags} -O0 -lgpiod
framework = arduino
board = linux_hardware
lib_deps =
${arduino_base.lib_deps}
rweather/Crypto
; The GenieBlocks LORA prototype board
; note: @geeksville disabled because genieblocks_lora is not checked into the boards directory, please send in a PR to add it ;-)
;[env:genieblocks_lora]
;extends = esp32_base
;board = genieblocks_lora
;build_flags =
; ${esp32_base.build_flags} -D GENIEBLOCKS

2
proto

Submodule proto updated: 18fc4cdb52...07ed86d8b4

61
src/DebugConfiguration.h Normal file
View File

@@ -0,0 +1,61 @@
// DEBUG LED
#ifndef LED_INVERTED
#define LED_INVERTED 0 // define as 1 if LED is active low (on)
#endif
// -----------------------------------------------------------------------------
// DEBUG
// -----------------------------------------------------------------------------
#ifdef CONSOLE_MAX_BAUD
#define SERIAL_BAUD CONSOLE_MAX_BAUD
#else
#define SERIAL_BAUD 921600 // Serial debug baud rate
#endif
#include "SerialConsole.h"
#define DEBUG_PORT (*console) // Serial debug port
// What platforms should use SEGGER?
#ifdef NRF52_SERIES
// Always include the SEGGER code on NRF52 - because useful for debugging
#include "SEGGER_RTT.h"
// The channel we send stdout data to
#define SEGGER_STDOUT_CH 0
// Debug printing to segger console
#define SEGGER_MSG(...) SEGGER_RTT_printf(SEGGER_STDOUT_CH, __VA_ARGS__)
// If we are not on a NRF52840 (which has built in USB-ACM serial support) and we don't have serial pins hooked up, then we MUST
// use SEGGER for debug output
#if !defined(PIN_SERIAL_RX) && !defined(NRF52840_XXAA)
// No serial ports on this board - ONLY use segger in memory console
#define USE_SEGGER
#endif
#else
#define SERIAL0_RX_GPIO 3 // Always GPIO3 on ESP32
#endif
#ifdef USE_SEGGER
#define DEBUG_MSG(...) SEGGER_RTT_printf(0, __VA_ARGS__)
#else
#ifdef DEBUG_PORT
#define DEBUG_MSG(...) DEBUG_PORT.logDebug(__VA_ARGS__)
#else
#define DEBUG_MSG(...)
#endif
#endif
// -----------------------------------------------------------------------------
// AXP192 (Rev1-specific options)
// -----------------------------------------------------------------------------
#define GPS_POWER_CTRL_CH 3
#define LORA_POWER_CTRL_CH 2
// Default Bluetooth PIN
#define defaultBLEPin 123456

View File

@@ -42,7 +42,7 @@ class GPSStatus : public Status
} }
// preferred method // preferred method
GPSStatus(bool hasLock, bool isConnected, Position pos) GPSStatus(bool hasLock, bool isConnected, const Position& pos)
: Status() : Status()
{ {
this->hasLock = hasLock; this->hasLock = hasLock;
@@ -149,4 +149,4 @@ class GPSStatus : public Status
} // namespace meshtastic } // namespace meshtastic
extern meshtastic::GPSStatus *gpsStatus; extern meshtastic::GPSStatus *gpsStatus;

View File

@@ -47,7 +47,7 @@ template <class Callback, class T> class CallbackObserver : public Observer<T>
CallbackObserver(Callback *_objPtr, ObserverCallback _method) : objPtr(_objPtr), method(_method) {} CallbackObserver(Callback *_objPtr, ObserverCallback _method) : objPtr(_objPtr), method(_method) {}
protected: protected:
virtual int onNotify(T arg) { return (objPtr->*method)(arg); } virtual int onNotify(T arg) override { return (objPtr->*method)(arg); }
}; };
/** /**
@@ -104,4 +104,4 @@ template <class T> void Observer<T>::observe(Observable<T> *o)
observed = o; observed = o;
o->addObserver(this); o->addObserver(this);
} }

View File

@@ -75,7 +75,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
* *
* FIXME - use a lipo lookup table, the current % full is super wrong * FIXME - use a lipo lookup table, the current % full is super wrong
*/ */
virtual int getBattPercentage() virtual int getBattPercentage() override
{ {
float v = getBattVoltage(); float v = getBattVoltage();
@@ -94,7 +94,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
/** /**
* The raw voltage of the batteryin millivolts or NAN if unknown * The raw voltage of the batteryin millivolts or NAN if unknown
*/ */
virtual float getBattVoltage() virtual float getBattVoltage() override
{ {
#ifndef ADC_MULTIPLIER #ifndef ADC_MULTIPLIER
@@ -127,15 +127,15 @@ class AnalogBatteryLevel : public HasBatteryLevel
/** /**
* return true if there is a battery installed in this unit * return true if there is a battery installed in this unit
*/ */
virtual bool isBatteryConnect() { return getBattPercentage() != -1; } virtual bool isBatteryConnect() override { return getBattPercentage() != -1; }
/// If we see a battery voltage higher than physics allows - assume charger is pumping /// If we see a battery voltage higher than physics allows - assume charger is pumping
/// in power /// in power
virtual bool isVBUSPlug() { return getBattVoltage() > chargingVolt; } virtual bool isVBUSPlug() override { return getBattVoltage() > chargingVolt; }
/// Assume charging if we have a battery and external power is connected. /// Assume charging if we have a battery and external power is connected.
/// we can't be smart enough to say 'full'? /// we can't be smart enough to say 'full'?
virtual bool isChargeing() { return isBatteryConnect() && isVBUSPlug(); } virtual bool isChargeing() override { return isBatteryConnect() && isVBUSPlug(); }
private: private:
/// If we see a battery voltage higher than physics allows - assume charger is pumping /// If we see a battery voltage higher than physics allows - assume charger is pumping
@@ -149,7 +149,10 @@ class AnalogBatteryLevel : public HasBatteryLevel
AnalogBatteryLevel analogLevel; AnalogBatteryLevel analogLevel;
Power::Power() : OSThread("Power") {} Power::Power() : OSThread("Power") {
statusHandler = {};
low_voltage_counter = 0;
}
bool Power::analogInit() bool Power::analogInit()
{ {
@@ -232,18 +235,18 @@ void Power::readPowerStatus()
} }
// Notify any status instances that are observing us // Notify any status instances that are observing us
const PowerStatus powerStatus = const PowerStatus powerStatus2 =
PowerStatus(hasBattery ? OptTrue : OptFalse, batteryLevel->isVBUSPlug() ? OptTrue : OptFalse, PowerStatus(hasBattery ? OptTrue : OptFalse, batteryLevel->isVBUSPlug() ? OptTrue : OptFalse,
batteryLevel->isChargeing() ? OptTrue : OptFalse, batteryVoltageMv, batteryChargePercent); batteryLevel->isChargeing() ? OptTrue : OptFalse, batteryVoltageMv, batteryChargePercent);
DEBUG_MSG("Battery: usbPower=%d, isCharging=%d, batMv=%d, batPct=%d\n", powerStatus.getHasUSB(), DEBUG_MSG("Battery: usbPower=%d, isCharging=%d, batMv=%d, batPct=%d\n", powerStatus2.getHasUSB(),
powerStatus.getIsCharging(), powerStatus.getBatteryVoltageMv(), powerStatus.getBatteryChargePercent()); powerStatus2.getIsCharging(), powerStatus2.getBatteryVoltageMv(), powerStatus2.getBatteryChargePercent());
newStatus.notifyObservers(&powerStatus); 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 // 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 // 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 NRF52_SERIES
if (powerStatus.getHasBattery() && !powerStatus.getHasUSB()){ if (powerStatus2.getHasBattery() && !powerStatus2.getHasUSB()){
if (batteryLevel->getBattVoltage() < MIN_BAT_MILLIVOLTS){ if (batteryLevel->getBattVoltage() < MIN_BAT_MILLIVOLTS){
low_voltage_counter++; low_voltage_counter++;
if (low_voltage_counter>3) if (low_voltage_counter>3)
@@ -254,13 +257,13 @@ void Power::readPowerStatus()
} }
#else #else
// If we have a battery at all and it is less than 10% full, force deep sleep // If we have a battery at all and it is less than 10% full, force deep sleep
if (powerStatus.getHasBattery() && !powerStatus.getHasUSB() && batteryLevel->getBattVoltage() < MIN_BAT_MILLIVOLTS) if (powerStatus2.getHasBattery() && !powerStatus2.getHasUSB() && batteryLevel->getBattVoltage() < MIN_BAT_MILLIVOLTS)
powerFSM.trigger(EVENT_LOW_BATTERY); powerFSM.trigger(EVENT_LOW_BATTERY);
#endif #endif
} else { } else {
// No power sensing on this board - tell everyone else we have no idea what is happening // No power sensing on this board - tell everyone else we have no idea what is happening
const PowerStatus powerStatus = PowerStatus(OptUnknown, OptUnknown, OptUnknown, -1, -1); const PowerStatus powerStatus3 = PowerStatus(OptUnknown, OptUnknown, OptUnknown, -1, -1);
newStatus.notifyObservers(&powerStatus); newStatus.notifyObservers(&powerStatus3);
} }
} }

View File

@@ -63,7 +63,6 @@ static void lsIdle()
// DEBUG_MSG("lsIdle begin ls_secs=%u\n", getPref_ls_secs()); // DEBUG_MSG("lsIdle begin ls_secs=%u\n", getPref_ls_secs());
#ifndef NO_ESP32 #ifndef NO_ESP32
esp_sleep_source_t wakeCause = ESP_SLEEP_WAKEUP_UNDEFINED;
// Do we have more sleeping to do? // Do we have more sleeping to do?
if (secsSlept < getPref_ls_secs()) { if (secsSlept < getPref_ls_secs()) {
@@ -73,14 +72,14 @@ static void lsIdle()
// If some other service would stall sleep, don't let sleep happen yet // If some other service would stall sleep, don't let sleep happen yet
if (doPreflightSleep()) { if (doPreflightSleep()) {
setLed(false); // Never leave led on while in light sleep setLed(false); // Never leave led on while in light sleep
wakeCause = doLightSleep(sleepTime * 1000LL); esp_sleep_source_t wakeCause2 = doLightSleep(sleepTime * 1000LL);
switch (wakeCause) { switch (wakeCause2) {
case ESP_SLEEP_WAKEUP_TIMER: case ESP_SLEEP_WAKEUP_TIMER:
// Normal case: timer expired, we should just go back to sleep ASAP // Normal case: timer expired, we should just go back to sleep ASAP
setLed(true); // briefly turn on led setLed(true); // briefly turn on led
wakeCause = doLightSleep(1); // leave led on for 1ms wakeCause2 = doLightSleep(1); // leave led on for 1ms
secsSlept += sleepTime; secsSlept += sleepTime;
// DEBUG_MSG("sleeping, flash led!\n"); // DEBUG_MSG("sleeping, flash led!\n");
@@ -94,7 +93,7 @@ static void lsIdle()
default: default:
// We woke for some other reason (button press, device interrupt) // We woke for some other reason (button press, device interrupt)
// uint64_t status = esp_sleep_get_ext1_wakeup_status(); // uint64_t status = esp_sleep_get_ext1_wakeup_status();
DEBUG_MSG("wakeCause %d\n", wakeCause); DEBUG_MSG("wakeCause2 %d\n", wakeCause2);
#ifdef BUTTON_PIN #ifdef BUTTON_PIN
bool pressed = !digitalRead(BUTTON_PIN); bool pressed = !digitalRead(BUTTON_PIN);

7
src/RF95Configuration.h Normal file
View File

@@ -0,0 +1,7 @@
// TODO refactor this out with better radio configuration system
#ifdef USE_RF95
#define RF95_RESET LORA_RESET
#define RF95_IRQ LORA_DIO0 // on SX1262 version this is a no connect DIO0
#define RF95_DIO1 LORA_DIO1 // Note: not really used for RF95
#define RF95_DIO2 LORA_DIO2 // Note: not really used for RF95
#endif

View File

@@ -22,7 +22,7 @@ class RedirectablePrint : public Print
volatile bool inDebugPrint = false; volatile bool inDebugPrint = false;
public: public:
RedirectablePrint(Print *_dest) : dest(_dest) {} explicit RedirectablePrint(Print *_dest) : dest(_dest) {}
/** /**
* Set a new destination * Set a new destination
@@ -56,4 +56,4 @@ class NoopPrint : public Print
/** /**
* A printer that doesn't go anywhere * A printer that doesn't go anywhere
*/ */
extern NoopPrint noopPrint; extern NoopPrint noopPrint;

View File

@@ -15,9 +15,9 @@ class SerialConsole : public StreamAPI, public RedirectablePrint
* we override this to notice when we've received a protobuf over the serial stream. Then we shunt off * we override this to notice when we've received a protobuf over the serial stream. Then we shunt off
* debug serial output. * debug serial output.
*/ */
virtual bool handleToRadio(const uint8_t *buf, size_t len); virtual bool handleToRadio(const uint8_t *buf, size_t len) override;
virtual size_t write(uint8_t c) virtual size_t write(uint8_t c) override
{ {
if (c == '\n') // prefix any newlines with carriage return if (c == '\n') // prefix any newlines with carriage return
RedirectablePrint::write('\r'); RedirectablePrint::write('\r');
@@ -27,7 +27,7 @@ class SerialConsole : public StreamAPI, public RedirectablePrint
protected: protected:
/// Check the current underlying physical link to see if the client is currently connected /// Check the current underlying physical link to see if the client is currently connected
virtual bool checkIsConnected(); virtual bool checkIsConnected() override;
}; };
// A simple wrapper to allow non class aware code write to the console // A simple wrapper to allow non class aware code write to the console

View File

@@ -2,21 +2,20 @@
#include "NodeDB.h" #include "NodeDB.h"
#include "configuration.h" #include "configuration.h"
AirTime *airTime = NULL;
AirTime *airTime;
// Don't read out of this directly. Use the helper functions. // Don't read out of this directly. Use the helper functions.
void AirTime::logAirtime(reportTypes reportType, uint32_t airtime_ms) void AirTime::logAirtime(reportTypes reportType, uint32_t airtime_ms)
{ {
// TODO: Is the airtimes array still necessary? It's now in myNodeInfo anyway
if (reportType == TX_LOG) { if (reportType == TX_LOG) {
DEBUG_MSG("AirTime - Packet transmitted : %ums\n", airtime_ms); DEBUG_MSG("AirTime - Packet transmitted : %ums\n", airtime_ms);
this->airtimes.periodTX[0] = this->airtimes.periodTX[0] + airtime_ms; this->airtimes.periodTX[0] = this->airtimes.periodTX[0] + airtime_ms;
myNodeInfo.air_period_tx[0] = myNodeInfo.air_period_tx[0] + airtime_ms; myNodeInfo.air_period_tx[0] = myNodeInfo.air_period_tx[0] + airtime_ms;
this->utilizationTX[this->getPeriodUtilHour()] = this->utilizationTX[this->getPeriodUtilHour()] + airtime_ms;
} else if (reportType == RX_LOG) { } else if (reportType == RX_LOG) {
DEBUG_MSG("AirTime - Packet received : %ums\n", airtime_ms); DEBUG_MSG("AirTime - Packet received : %ums\n", airtime_ms);
this->airtimes.periodRX[0] = this->airtimes.periodRX[0] + airtime_ms; this->airtimes.periodRX[0] = this->airtimes.periodRX[0] + airtime_ms;
@@ -26,8 +25,8 @@ void AirTime::logAirtime(reportTypes reportType, uint32_t airtime_ms)
this->airtimes.periodRX_ALL[0] = this->airtimes.periodRX_ALL[0] + airtime_ms; this->airtimes.periodRX_ALL[0] = this->airtimes.periodRX_ALL[0] + airtime_ms;
} }
uint8_t channelUtilPeriod = (getSecondsSinceBoot() / 10) % CHANNEL_UTILIZATION_PERIODS; // Log all airtime type for channel utilization
this->channelUtilization[channelUtilPeriod] = channelUtilization[channelUtilPeriod] + airtime_ms; this->channelUtilization[this->getPeriodUtilMinute()] = channelUtilization[this->getPeriodUtilMinute()] + airtime_ms;
} }
uint8_t AirTime::currentPeriodIndex() uint8_t AirTime::currentPeriodIndex()
@@ -35,21 +34,29 @@ uint8_t AirTime::currentPeriodIndex()
return ((getSecondsSinceBoot() / SECONDS_PER_PERIOD) % PERIODS_TO_LOG); return ((getSecondsSinceBoot() / SECONDS_PER_PERIOD) % PERIODS_TO_LOG);
} }
uint8_t AirTime::getPeriodUtilMinute() {
return (getSecondsSinceBoot() / 10) % CHANNEL_UTILIZATION_PERIODS;
}
uint8_t AirTime::getPeriodUtilHour() {
return (getSecondsSinceBoot() / 60) % MINUTES_IN_HOUR;
}
void AirTime::airtimeRotatePeriod() void AirTime::airtimeRotatePeriod()
{ {
if (this->airtimes.lastPeriodIndex != currentPeriodIndex()) { if (this->airtimes.lastPeriodIndex != this->currentPeriodIndex()) {
DEBUG_MSG("Rotating airtimes to a new period = %u\n", currentPeriodIndex()); DEBUG_MSG("Rotating airtimes to a new period = %u\n", this->currentPeriodIndex());
for (int i = PERIODS_TO_LOG - 2; i >= 0; --i) { for (int i = PERIODS_TO_LOG - 2; i >= 0; --i) {
this->airtimes.periodTX[i + 1] = this->airtimes.periodTX[i]; this->airtimes.periodTX[i + 1] = this->airtimes.periodTX[i];
this->airtimes.periodRX[i + 1] = this->airtimes.periodRX[i]; this->airtimes.periodRX[i + 1] = this->airtimes.periodRX[i];
this->airtimes.periodRX_ALL[i + 1] = this->airtimes.periodRX_ALL[i]; this->airtimes.periodRX_ALL[i + 1] = this->airtimes.periodRX_ALL[i];
myNodeInfo.air_period_tx[i + 1] = myNodeInfo.air_period_tx[i]; myNodeInfo.air_period_tx[i + 1] = this->airtimes.periodTX[i];
myNodeInfo.air_period_rx[i + 1] = myNodeInfo.air_period_rx[i]; myNodeInfo.air_period_rx[i + 1] = this->airtimes.periodRX[i];
} }
this->airtimes.periodTX[0] = 0; this->airtimes.periodTX[0] = 0;
this->airtimes.periodRX[0] = 0; this->airtimes.periodRX[0] = 0;
this->airtimes.periodRX_ALL[0] = 0; this->airtimes.periodRX_ALL[0] = 0;
@@ -57,7 +64,7 @@ void AirTime::airtimeRotatePeriod()
myNodeInfo.air_period_tx[0] = 0; myNodeInfo.air_period_tx[0] = 0;
myNodeInfo.air_period_rx[0] = 0; myNodeInfo.air_period_rx[0] = 0;
this->airtimes.lastPeriodIndex = currentPeriodIndex(); this->airtimes.lastPeriodIndex = this->currentPeriodIndex();
} }
} }
@@ -100,25 +107,53 @@ float AirTime::channelUtilizationPercent()
return (float(sum) / float(CHANNEL_UTILIZATION_PERIODS * 10 * 1000)) * 100; return (float(sum) / float(CHANNEL_UTILIZATION_PERIODS * 10 * 1000)) * 100;
} }
AirTime::AirTime() : concurrency::OSThread("AirTime") {} float AirTime::utilizationTXPercent()
{
uint32_t sum = 0;
for (uint32_t i = 0; i < MINUTES_IN_HOUR; i++) {
sum += this->utilizationTX[i];
}
return (float(sum) / float(MS_IN_HOUR)) * 100;
}
AirTime::AirTime() : concurrency::OSThread("AirTime"),airtimes({}) {
}
int32_t AirTime::runOnce() int32_t AirTime::runOnce()
{ {
secSinceBoot++; secSinceBoot++;
uint8_t utilPeriod = (getSecondsSinceBoot() / 10) % CHANNEL_UTILIZATION_PERIODS; uint8_t utilPeriod = this->getPeriodUtilMinute();
uint8_t utilPeriodTX = this->getPeriodUtilHour();
if (firstTime) { if (firstTime) {
airtimeRotatePeriod();
// Init utilizationTX window to all 0
for (uint32_t i = 0; i < MINUTES_IN_HOUR; i++) {
this->utilizationTX[i] = 0;
}
// Init channelUtilization window to all 0
for (uint32_t i = 0; i < CHANNEL_UTILIZATION_PERIODS; i++) { for (uint32_t i = 0; i < CHANNEL_UTILIZATION_PERIODS; i++) {
this->channelUtilization[i] = 0; this->channelUtilization[i] = 0;
} }
// Init airtime windows to all 0
for (int i = 0; i < PERIODS_TO_LOG; i++) {
this->airtimes.periodTX[i] = 0;
this->airtimes.periodRX[i] = 0;
this->airtimes.periodRX_ALL[i] = 0;
// myNodeInfo.air_period_tx[i] = 0;
// myNodeInfo.air_period_rx[i] = 0;
}
firstTime = false; firstTime = false;
lastUtilPeriod = utilPeriod; lastUtilPeriod = utilPeriod;
} else { } else {
this->airtimeRotatePeriod();
// Reset the channelUtilization window when we roll over // Reset the channelUtilization window when we roll over
if (lastUtilPeriod != utilPeriod) { if (lastUtilPeriod != utilPeriod) {
@@ -127,9 +162,26 @@ int32_t AirTime::runOnce()
this->channelUtilization[utilPeriod] = 0; this->channelUtilization[utilPeriod] = 0;
} }
if (lastUtilPeriodTX != utilPeriodTX) {
lastUtilPeriodTX = utilPeriodTX;
this->utilizationTX[utilPeriodTX] = 0;
}
// Update channel_utilization every second. // Update channel_utilization every second.
myNodeInfo.channel_utilization = airTime->channelUtilizationPercent(); myNodeInfo.channel_utilization = airTime->channelUtilizationPercent();
}
// Update channel_utilization every second.
myNodeInfo.air_util_tx = airTime->utilizationTXPercent();
}
/*
DEBUG_MSG("utilPeriodTX %d TX Airtime %3.2f%\n", utilPeriodTX, airTime->utilizationTXPercent());
for (uint32_t i = 0; i < MINUTES_IN_HOUR; i++) {
DEBUG_MSG(
"%d,", this->utilizationTX[i]
);
}
DEBUG_MSG("\n");
*/
return (1000 * 1); return (1000 * 1);
} }

View File

@@ -27,6 +27,9 @@
#define CHANNEL_UTILIZATION_PERIODS 6 #define CHANNEL_UTILIZATION_PERIODS 6
#define SECONDS_PER_PERIOD 3600 #define SECONDS_PER_PERIOD 3600
#define PERIODS_TO_LOG 24 #define PERIODS_TO_LOG 24
#define MINUTES_IN_HOUR 60
#define SECONDS_IN_MINUTE 60
#define MS_IN_HOUR (MINUTES_IN_HOUR * SECONDS_IN_MINUTE * 1000)
enum reportTypes { TX_LOG, RX_LOG, RX_ALL_LOG }; enum reportTypes { TX_LOG, RX_LOG, RX_ALL_LOG };
@@ -43,9 +46,12 @@ class AirTime : private concurrency::OSThread
void logAirtime(reportTypes reportType, uint32_t airtime_ms); void logAirtime(reportTypes reportType, uint32_t airtime_ms);
float channelUtilizationPercent(); float channelUtilizationPercent();
uint32_t channelUtilization[CHANNEL_UTILIZATION_PERIODS]; float utilizationTXPercent();
float UtilizationPercentTX();
uint32_t channelUtilization[CHANNEL_UTILIZATION_PERIODS] = {0};
uint32_t utilizationTX[MINUTES_IN_HOUR] = {0};
uint8_t currentPeriodIndex();
void airtimeRotatePeriod(); void airtimeRotatePeriod();
uint8_t getPeriodsToLog(); uint8_t getPeriodsToLog();
uint32_t getSecondsPerPeriod(); uint32_t getSecondsPerPeriod();
@@ -55,6 +61,7 @@ class AirTime : private concurrency::OSThread
private: private:
bool firstTime = true; bool firstTime = true;
uint8_t lastUtilPeriod = 0; uint8_t lastUtilPeriod = 0;
uint8_t lastUtilPeriodTX = 0;
uint32_t secSinceBoot = 0; uint32_t secSinceBoot = 0;
struct airtimeStruct { struct airtimeStruct {
@@ -64,8 +71,12 @@ class AirTime : private concurrency::OSThread
uint8_t lastPeriodIndex; uint8_t lastPeriodIndex;
} airtimes; } airtimes;
uint8_t getPeriodUtilMinute();
uint8_t getPeriodUtilHour();
uint8_t currentPeriodIndex();
protected: protected:
virtual int32_t runOnce() override; virtual int32_t runOnce() override;
}; };
extern AirTime *airTime; extern AirTime *airTime;

View File

@@ -13,4 +13,5 @@ enum class Cmd {
STOP_BLUETOOTH_PIN_SCREEN, STOP_BLUETOOTH_PIN_SCREEN,
STOP_BOOT_SCREEN, STOP_BOOT_SCREEN,
PRINT, PRINT,
START_SHUTDOWN_SCREEN,
}; };

View File

@@ -7,9 +7,8 @@
namespace concurrency namespace concurrency
{ {
BinarySemaphoreFreeRTOS::BinarySemaphoreFreeRTOS() BinarySemaphoreFreeRTOS::BinarySemaphoreFreeRTOS() : semaphore(xSemaphoreCreateBinary())
{ {
semaphore = xSemaphoreCreateBinary();
assert(semaphore); assert(semaphore);
} }
@@ -38,4 +37,4 @@ IRAM_ATTR void BinarySemaphoreFreeRTOS::giveFromISR(BaseType_t *pxHigherPriority
} // namespace concurrency } // namespace concurrency
#endif #endif

View File

@@ -6,9 +6,8 @@ namespace concurrency
{ {
#ifdef HAS_FREE_RTOS #ifdef HAS_FREE_RTOS
Lock::Lock() Lock::Lock() : handle(xSemaphoreCreateBinary())
{ {
handle = xSemaphoreCreateBinary();
assert(handle); assert(handle);
assert(xSemaphoreGive(handle)); assert(xSemaphoreGive(handle));
} }

View File

@@ -10,7 +10,7 @@ namespace concurrency {
class LockGuard class LockGuard
{ {
public: public:
LockGuard(Lock *lock); explicit LockGuard(Lock *lock);
~LockGuard(); ~LockGuard();
LockGuard(const LockGuard &) = delete; LockGuard(const LockGuard &) = delete;

View File

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

View File

@@ -18,7 +18,7 @@ class Periodic : public OSThread
Periodic(const char *name, int32_t (*_callback)()) : OSThread(name), callback(_callback) {} Periodic(const char *name, int32_t (*_callback)()) : OSThread(name), callback(_callback) {}
protected: protected:
int32_t runOnce() { return callback(); } int32_t runOnce() override { return callback(); }
}; };
} // namespace concurrency } // namespace concurrency

View File

@@ -45,10 +45,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// If we are using the JTAG port for debugging, some pins must be left free for that (and things like GPS have to be disabled) // If we are using the JTAG port for debugging, some pins must be left free for that (and things like GPS have to be disabled)
// we don't support jtag on the ttgo - access to gpio 12 is a PITA // we don't support jtag on the ttgo - access to gpio 12 is a PITA
#ifdef ARDUINO_HELTEC_WIFI_LORA_32_V2
//#define USE_JTAG
#endif
#define REQUIRE_RADIO true // If true, we will fail to start if the radio is not found #define REQUIRE_RADIO true // If true, we will fail to start if the radio is not found
/// Convert a preprocessor name into a quoted string /// Convert a preprocessor name into a quoted string
@@ -88,18 +84,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define BUTTON_PIN_TOUCH PIN_BUTTON_TOUCH #define BUTTON_PIN_TOUCH PIN_BUTTON_TOUCH
#endif #endif
// FIXME, use variant.h defs for all of this!!! (even on the ESP32 targets)
#elif defined(CubeCell_BoardPlus)
//
// Standard definitions for CubeCell targets
//
#define NO_ESP32 // Don't use ESP32 libs (mainly bluetooth)
#define LED_PIN -1 // FIXME totally bogus
#define BUTTON_PIN -1
#else #else
// //
@@ -169,338 +153,51 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// This string must exactly match the case used in release file names or the android updater won't work // This string must exactly match the case used in release file names or the android updater won't work
#define HW_VENDOR HardwareModel_TBEAM #define HW_VENDOR HardwareModel_TBEAM
// #define BUTTON_NEED_PULLUP // if set we need to turn on the internal CPU pullup during sleep
#define I2C_SDA 21
#define I2C_SCL 22
#define BUTTON_PIN 38 // The middle button GPIO on the T-Beam
//#define BUTTON_PIN_ALT 13 // Alternate GPIO for an external button if needed. Does anyone use this? It is not documented anywhere.
#define EXT_NOTIFY_OUT 13 // Default pin to use for Ext Notify Plugin.
#define LED_INVERTED 1
#define LED_PIN 4 // Newer tbeams (1.1) have an extra led on GPIO4
// TTGO uses a common pinout for their SX1262 vs RF95 modules - both can be enabled and we will probe at runtime for RF95 and if
// not found then probe for SX1262
#define USE_RF95
#define USE_SX1262
#define LORA_DIO0 26 // a No connect on the SX1262 module
#define LORA_RESET 23
#define LORA_DIO1 33 // SX1262 IRQ
#define LORA_DIO2 32 // SX1262 BUSY
#define LORA_DIO3 // Not connected on PCB, but internally on the TTGO SX1262, if DIO3 is high the TXCO is enabled
#ifdef USE_SX1262
#define SX126X_CS RF95_NSS // FIXME - we really should define LORA_CS instead
#define SX126X_DIO1 LORA_DIO1
#define SX126X_BUSY LORA_DIO2
#define SX126X_RESET LORA_RESET
#define SX126X_E22 // Not really an E22 but TTGO seems to be trying to clone that
// Internally the TTGO module hooks the SX1262-DIO2 in to control the TX/RX switch (which is the default for the sx1262interface
// code)
#endif
// Leave undefined to disable our PMU IRQ handler. DO NOT ENABLE THIS because the pmuirq can cause sperious interrupts
// and waking from light sleep
// #define PMU_IRQ 35
#define AXP192_SLAVE_ADDRESS 0x34
#elif defined(TBEAM_V07) #elif defined(TBEAM_V07)
// This string must exactly match the case used in release file names or the android updater won't work // This string must exactly match the case used in release file names or the android updater won't work
#define HW_VENDOR HardwareModel_TBEAM0p7 #define HW_VENDOR HardwareModel_TBEAM0p7
// #define BUTTON_NEED_PULLUP // if set we need to turn on the internal CPU pullup during sleep
#define I2C_SDA 21
#define I2C_SCL 22
#define BUTTON_PIN 39
#define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
#define EXT_NOTIFY_OUT 13 // Default pin to use for Ext Notify Plugin.
#define USE_RF95
#define LORA_DIO0 26 // a No connect on the SX1262 module
#define LORA_RESET 23
#define LORA_DIO1 33 // Not really used
#define LORA_DIO2 32 // Not really used
// This board has different GPS pins than all other boards
#undef GPS_RX_PIN
#undef GPS_TX_PIN
#define GPS_RX_PIN 12
#define GPS_TX_PIN 15
#elif defined(DIY_V1) #elif defined(DIY_V1)
// This string must exactly match the case used in release file names or the android updater won't work // This string must exactly match the case used in release file names or the android updater won't work
#define HW_VENDOR HardwareModel_DIY_V1 #define HW_VENDOR HardwareModel_DIY_V1
// For OLED LCD
#define I2C_SDA 21
#define I2C_SCL 22
// GPS
#undef GPS_RX_PIN
#define GPS_RX_PIN 15
//#undef GPS_TX_PIN
//#define GPS_TX_PIN 12 // not connected
#define BUTTON_PIN 39 // The middle button GPIO on the T-Beam
#define EXT_NOTIFY_OUT 12 // Overridden default pin to use for Ext Notify Plugin (#975).
#define LED_PIN 2 // add status LED (compatible with core-pcb and DIY targets)
#define LORA_DIO0 26 // a No connect on the SX1262/SX1268 module
#define LORA_RESET 23 // RST for SX1276, and for SX1262/SX1268
#define LORA_DIO1 33 // IRQ for SX1262/SX1268
#define LORA_DIO2 32 // BUSY for SX1262/SX1268
#define LORA_DIO3 // Not connected on PCB, but internally on the TTGO SX1262/SX1268, if DIO3 is high the TXCO is enabled
#define RF95_SCK 5
#define RF95_MISO 19
#define RF95_MOSI 27
#define RF95_NSS 18
// supported modules list
#define USE_SX1262
#define USE_SX1268
#define USE_LLCC68
// common pinouts for SX126X modules
#define SX126X_CS 18 // NSS for SX126X
#define SX126X_DIO1 LORA_DIO1
#define SX126X_BUSY LORA_DIO2
#define SX126X_RESET LORA_RESET
#define SX126X_RXEN 14
#define SX126X_TXEN 13
#ifdef EBYTE_E22
// Internally the TTGO module hooks the SX126x-DIO2 in to control the TX/RX switch
// (which is the default for the sx1262interface code)
#define SX126X_E22
#endif
#elif defined(ARDUINO_HELTEC_WIFI_LORA_32_V2) #elif defined(ARDUINO_HELTEC_WIFI_LORA_32_V2)
// the default ESP32 Pin of 15 is the Oled SCL, set to 36 and 37 and works fine.
// Tested on Neo6m module.
#undef GPS_RX_PIN
#undef GPS_TX_PIN
#define GPS_RX_PIN 36
#define GPS_TX_PIN 37
#ifndef USE_JTAG // gpio15 is TDO for JTAG, so no I2C on this board while doing jtag
#define I2C_SDA 4 // I2C pins for this board
#define I2C_SCL 15
#endif
#define RESET_OLED 16 // If defined, this pin will be used to reset the display controller
#define VEXT_ENABLE 21 // active low, powers the oled display and the lora antenna boost
#define LED_PIN 25 // If defined we will blink this LED
#define BUTTON_PIN 0 // If defined, this will be used for user button presses
#define USE_RF95
#define LORA_DIO0 26 // a No connect on the SX1262 module
#ifndef USE_JTAG
#define LORA_RESET 14
#endif
#define LORA_DIO1 35 // Not really used
#define LORA_DIO2 34 // Not really used
// ratio of voltage divider = 3.20 (R1=100k, R2=220k)
#define ADC_MULTIPLIER 3.2
#ifdef HELTEC_V2_0 #ifdef HELTEC_V2_0
// This string must exactly match the case used in release file names or the android updater won't work // This string must exactly match the case used in release file names or the android updater won't work
#define HW_VENDOR HardwareModel_HELTEC_V2_0 #define HW_VENDOR HardwareModel_HELTEC_V2_0
#define BATTERY_PIN 13 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
#endif #endif
#ifdef HELTEC_V2_1 #ifdef HELTEC_V2_1
// This string must exactly match the case used in release file names or the android updater won't work // This string must exactly match the case used in release file names or the android updater won't work
#define HW_VENDOR HardwareModel_HELTEC_V2_1 #define HW_VENDOR HardwareModel_HELTEC_V2_1
#define BATTERY_PIN 37 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
#define EXT_NOTIFY_OUT 13 // Default pin to use for Ext Notify Plugin.
#endif #endif
#elif defined(ARDUINO_HELTEC_WIFI_LORA_32) #elif defined(ARDUINO_HELTEC_WIFI_LORA_32)
// the default ESP32 Pin of 15 is the Oled SCL, set to 36 and 37 and works fine.
// Tested on Neo6m module.
#undef GPS_RX_PIN
#undef GPS_TX_PIN
#define GPS_RX_PIN 36
#define GPS_TX_PIN 37
#ifndef USE_JTAG // gpio15 is TDO for JTAG, so no I2C on this board while doing jtag
#define I2C_SDA 4 // I2C pins for this board
#define I2C_SCL 15
#endif
#define RESET_OLED 16 // If defined, this pin will be used to reset the display controller
#define LED_PIN 25 // If defined we will blink this LED
#define BUTTON_PIN 0 // If defined, this will be used for user button presses
#define USE_RF95
#define LORA_DIO0 26 // a No connect on the SX1262 module
#ifndef USE_JTAG
#define LORA_RESET 14
#endif
#define LORA_DIO1 33 // Not really used
#define LORA_DIO2 32 // Not really used
// ratio of voltage divider = 3.20 (R1=100k, R2=220k)
#define ADC_MULTIPLIER 3.2
// This string must exactly match the case used in release file names or the android updater won't work
#define HW_VENDOR HardwareModel_HELTEC_V1 #define HW_VENDOR HardwareModel_HELTEC_V1
#define BATTERY_PIN 13 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
#elif defined(TLORA_V1) #elif defined(TLORA_V1)
// This string must exactly match the case used in release file names or the android updater won't work
#define HW_VENDOR HardwareModel_TLORA_V1 #define HW_VENDOR HardwareModel_TLORA_V1
#undef GPS_RX_PIN
#undef GPS_TX_PIN
#define GPS_RX_PIN 36
#define GPS_TX_PIN 37
#define I2C_SDA 4 // I2C pins for this board
#define I2C_SCL 15
#define RESET_OLED 16 // If defined, this pin will be used to reset the display controller
// #define VEXT_ENABLE 21 // active low, powers the oled display and the lora antenna boost
#define LED_PIN 2 // If defined we will blink this LED
#define BUTTON_PIN 0 // If defined, this will be used for user button presses
#define BUTTON_NEED_PULLUP
#define EXT_NOTIFY_OUT 13 // Default pin to use for Ext Notify Plugin.
#define USE_RF95
#define LORA_DIO0 26 // a No connect on the SX1262 module
#define LORA_RESET 14
#define LORA_DIO1 35 // Not really used
#define LORA_DIO2 34 // Not really used
#elif defined(TLORA_V2) #elif defined(TLORA_V2)
// This string must exactly match the case used in release file names or the android updater won't work // 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 #define HW_VENDOR HardwareModel_TLORA_V2
#undef GPS_RX_PIN
#undef GPS_TX_PIN
#define GPS_RX_PIN 36
#define GPS_TX_PIN 13 // per @eugene
#define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
#define I2C_SDA 21 // I2C pins for this board
#define I2C_SCL 22
#define RESET_OLED 16 // If defined, this pin will be used to reset the display controller
#define VEXT_ENABLE 21 // active low, powers the oled display and the lora antenna boost
#define LED_PIN 25 // If defined we will blink this LED
#define BUTTON_PIN \
0 // If defined, this will be used for user button presses, if your board doesn't have a physical switch, you can wire one
// between this pin and ground
#define BUTTON_NEED_PULLUP
#define USE_RF95
#define LORA_DIO0 26 // a No connect on the SX1262 module
#define LORA_RESET 14
#define LORA_DIO1 35 // Not really used
#define LORA_DIO2 34 // Not really used
#elif defined(TLORA_V1_3) #elif defined(TLORA_V1_3)
// This string must exactly match the case used in release file names or the android updater won't work // 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 #define HW_VENDOR HardwareModel_TLORA_V1_1p3
#undef GPS_RX_PIN
#undef GPS_TX_PIN
#define GPS_RX_PIN 36
#define GPS_TX_PIN 13 // per @eugene
#define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
#define I2C_SDA 4 // I2C pins for this board
#define I2C_SCL 15
#define RESET_OLED 16 // If defined, this pin will be used to reset the display controller
#define VEXT_ENABLE 21 // active low, powers the oled display and the lora antenna boost
#define LED_PIN 25 // If defined we will blink this LED
#define BUTTON_PIN 36
#define BUTTON_NEED_PULLUP
#define USE_RF95
#define LORA_DIO0 26 // a No connect on the SX1262 module
#define LORA_RESET 14
#define LORA_DIO1 35 // Not really used
#define LORA_DIO2 34 // Not really used
#elif defined(TLORA_V2_1_16) #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 // 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 #define HW_VENDOR HardwareModel_TLORA_V2_1_1p6
#undef GPS_RX_PIN
#undef GPS_TX_PIN
#define GPS_RX_PIN 15 // per @der_bear on the forum, 36 is incorrect for this board type and 15 is a better pick
#define GPS_TX_PIN 13
#define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
#define I2C_SDA 21 // I2C pins for this board
#define I2C_SCL 22
#define RESET_OLED 16 // If defined, this pin will be used to reset the display controller
#define VEXT_ENABLE 21 // active low, powers the oled display and the lora antenna boost
#define LED_PIN 25 // If defined we will blink this LED
#define BUTTON_PIN 12 // If defined, this will be used for user button presses,
#define BUTTON_NEED_PULLUP
#define USE_RF95
#define LORA_DIO0 26 // a No connect on the SX1262 module
#define LORA_RESET 14
#define LORA_DIO1 35 // Not really used
#define LORA_DIO2 34 // Not really used
#elif defined(GENIEBLOCKS) #elif defined(GENIEBLOCKS)
// This string must exactly match the case used in release file names or the android updater won't work // This string must exactly match the case used in release file names or the android updater won't work
#define HW_VENDOR HardwareModel_GENIEBLOCKS #define HW_VENDOR HardwareModel_GENIEBLOCKS
#undef GPS_RX_PIN
#undef GPS_TX_PIN
#define GPS_RX_PIN 5
#define GPS_TX_PIN 18
#define GPS_RESET_N 10
#define GPS_EXTINT 23 // On MAX-M8 module pin name is EXTINT. On L70 module pin name is STANDBY.
#define BATTERY_PIN 39 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
#define BATTERY_EN_PIN 14 // Voltage voltage divider enable pin connected to mosfet
#define I2C_SDA 4 // I2C pins for this board
#define I2C_SCL 2
#define LED_PIN 12 // If defined we will blink this LED
//#define BUTTON_PIN 36 // If defined, this will be used for user button presses (ToDo problem on that line on debug screen -->
// Long press start!) #define BUTTON_NEED_PULLUP //GPIOs 34 to 39 are GPIs input only pins. These pins dont have internal
// pull-ups or pull-down resistors.
#define USE_RF95
#define LORA_DIO0 38 // a No connect on the SX1262 module
#define LORA_RESET 9
#define RF95_SCK 22
#define RF95_MISO 19
#define RF95_MOSI 13
#define RF95_NSS 21
#endif #endif
@@ -533,100 +230,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define HW_VENDOR HardwareModel_PORTDUINO #define HW_VENDOR HardwareModel_PORTDUINO
#define USE_SIM_RADIO
// Pine64 uses a common pinout for their SX1262 vs RF95 modules - both can be enabled and we will probe at runtime for RF95 and if
// not found then probe for SX1262. Currently the RF95 code is disabled because I think the RF95 module won't need to ship.
// #define USE_RF95
#define USE_SX1262
// Fake SPI device selections
#define RF95_SCK 5
#define RF95_MISO 19
#define RF95_MOSI 27
#define RF95_NSS RADIOLIB_NC // the ch341f spi controller does CS for us
#define LORA_DIO0 26 // a No connect on the SX1262 module
#define LORA_RESET 14
#define LORA_DIO1 33 // SX1262 IRQ, called DIO0 on pinelora schematic, pin 7 on ch341f "ack" - FIXME, enable hwints in linux
#define LORA_DIO2 32 // SX1262 BUSY, actually connected to "DIO5" on pinelora schematic, pin 8 on ch341f "slct"
#define LORA_DIO3 // Not connected on PCB, but internally on the TTGO SX1262, if DIO3 is high the TXCO is enabled
#ifdef USE_SX1262
#define SX126X_CS 20 // CS0 on pinelora schematic, hooked to gpio D0 on ch341f
#define SX126X_DIO1 LORA_DIO1
#define SX126X_BUSY LORA_DIO2
#define SX126X_RESET LORA_RESET
// HOPE RFM90 does not have a TCXO therefore not SX126X_E22
#endif #endif
#endif #include "variant.h"
#include "RF95Configuration.h"
// DEBUG LED #include "DebugConfiguration.h"
#ifndef LED_INVERTED
#define LED_INVERTED 0 // define as 1 if LED is active low (on)
#endif
#ifdef USE_RF95
#define RF95_RESET LORA_RESET
#define RF95_IRQ LORA_DIO0 // on SX1262 version this is a no connect DIO0
#define RF95_DIO1 LORA_DIO1 // Note: not really used for RF95
#define RF95_DIO2 LORA_DIO2 // Note: not really used for RF95
#endif
// -----------------------------------------------------------------------------
// DEBUG
// -----------------------------------------------------------------------------
#ifdef CONSOLE_MAX_BAUD
#define SERIAL_BAUD CONSOLE_MAX_BAUD
#else
#define SERIAL_BAUD 921600 // Serial debug baud rate
#endif
#include "SerialConsole.h"
#define DEBUG_PORT (*console) // Serial debug port
// What platforms should use SEGGER?
#ifdef NRF52_SERIES
// Always include the SEGGER code on NRF52 - because useful for debugging
#include "SEGGER_RTT.h"
// The channel we send stdout data to
#define SEGGER_STDOUT_CH 0
// Debug printing to segger console
#define SEGGER_MSG(...) SEGGER_RTT_printf(SEGGER_STDOUT_CH, __VA_ARGS__)
// If we are not on a NRF52840 (which has built in USB-ACM serial support) and we don't have serial pins hooked up, then we MUST
// use SEGGER for debug output
#if !defined(PIN_SERIAL_RX) && !defined(NRF52840_XXAA)
// No serial ports on this board - ONLY use segger in memory console
#define USE_SEGGER
#endif
#else
#define SERIAL0_RX_GPIO 3 // Always GPIO3 on ESP32
#endif
#ifdef USE_SEGGER
#define DEBUG_MSG(...) SEGGER_RTT_printf(0, __VA_ARGS__)
#else
#ifdef DEBUG_PORT
#define DEBUG_MSG(...) DEBUG_PORT.logDebug(__VA_ARGS__)
#else
#define DEBUG_MSG(...)
#endif
#endif
// -----------------------------------------------------------------------------
// AXP192 (Rev1-specific options)
// -----------------------------------------------------------------------------
#define GPS_POWER_CTRL_CH 3
#define LORA_POWER_CTRL_CH 2
// Default Bluetooth PIN
#define defaultBLEPin 123456

View File

@@ -58,7 +58,7 @@ int update_size_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_
return 0; return 0;
} }
#define MAX_BLOCKSIZE 512 #define MAX_BLOCKSIZE_FOR_BT 512
/// Handle writes to data /// Handle writes to data
int update_data_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)
@@ -66,7 +66,7 @@ int update_data_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_
concurrency::LockGuard g(updateLock); concurrency::LockGuard g(updateLock);
static uint8_t static uint8_t
data[MAX_BLOCKSIZE]; // we temporarily copy here because I'm worried that a fast sender might be able overwrite srcbuf data[MAX_BLOCKSIZE_FOR_BT]; // we temporarily copy here because I'm worried that a fast sender might be able overwrite srcbuf
uint16_t len = 0; uint16_t len = 0;

View File

@@ -32,7 +32,7 @@ class ESP32CryptoEngine : public CryptoEngine
* @param bytes a _static_ buffer that will remain valid for the life of this crypto instance (i.e. this class will cache the * @param bytes a _static_ buffer that will remain valid for the life of this crypto instance (i.e. this class will cache the
* provided pointer) * provided pointer)
*/ */
virtual void setKey(const CryptoKey &k) virtual void setKey(const CryptoKey &k) override
{ {
CryptoEngine::setKey(k); CryptoEngine::setKey(k);
@@ -47,7 +47,7 @@ class ESP32CryptoEngine : public CryptoEngine
* *
* @param bytes is updated in place * @param bytes is updated in place
*/ */
virtual void encrypt(uint32_t fromNode, uint64_t packetNum, size_t numBytes, uint8_t *bytes) virtual void encrypt(uint32_t fromNode, uint64_t packetNum, size_t numBytes, uint8_t *bytes) override
{ {
if (key.length > 0) { if (key.length > 0) {
uint8_t stream_block[16]; uint8_t stream_block[16];
@@ -66,7 +66,7 @@ class ESP32CryptoEngine : public CryptoEngine
} }
} }
virtual void decrypt(uint32_t fromNode, uint64_t packetNum, size_t numBytes, uint8_t *bytes) virtual void decrypt(uint32_t fromNode, uint64_t packetNum, size_t numBytes, uint8_t *bytes) override
{ {
// DEBUG_MSG("ESP32 decrypt!\n"); // DEBUG_MSG("ESP32 decrypt!\n");

View File

@@ -14,9 +14,9 @@
*/ */
class SimpleAllocator class SimpleAllocator
{ {
uint8_t bytes[POOL_SIZE]; uint8_t bytes[POOL_SIZE] = {};
uint32_t nextFree; uint32_t nextFree = 0;
public: public:
SimpleAllocator(); SimpleAllocator();
@@ -37,6 +37,6 @@ void *operator new(size_t size, SimpleAllocator &p);
*/ */
class AllocatorScope { class AllocatorScope {
public: public:
AllocatorScope(SimpleAllocator &a); explicit AllocatorScope(SimpleAllocator &a);
~AllocatorScope(); ~AllocatorScope();
}; };

View File

@@ -11,10 +11,10 @@ class Air530GPS : public NMEAGPS
{ {
protected: protected:
/// If possible force the GPS into sleep/low power mode /// If possible force the GPS into sleep/low power mode
virtual void sleep(); virtual void sleep() override;
/// wake the GPS into normal operation mode /// wake the GPS into normal operation mode
virtual void wake(); virtual void wake() override;
private: private:
/// Send a NMEA cmd with checksum /// Send a NMEA cmd with checksum

View File

@@ -145,7 +145,7 @@ class GPS : private concurrency::OSThread
*/ */
void publishUpdate(); void publishUpdate();
virtual int32_t runOnce(); virtual int32_t runOnce() override;
}; };
// Creates an instance of the GPS class. // Creates an instance of the GPS class.

View File

@@ -171,7 +171,7 @@ void GeoCoord::latLongToMGRS(const double lat, const double lon, MGRS &mgrs) {
* Based on: https://www.movable-type.co.uk/scripts/latlong-os-gridref.html * Based on: https://www.movable-type.co.uk/scripts/latlong-os-gridref.html
*/ */
void GeoCoord::latLongToOSGR(const double lat, const double lon, OSGR &osgr) { void GeoCoord::latLongToOSGR(const double lat, const double lon, OSGR &osgr) {
char letter[] = "ABCDEFGHJKLMNOPQRSTUVWXYZ"; // No 'I' in OSGR const char letter[] = "ABCDEFGHJKLMNOPQRSTUVWXYZ"; // No 'I' in OSGR
double a = 6377563.396; // Airy 1830 semi-major axis double a = 6377563.396; // Airy 1830 semi-major axis
double b = 6356256.909; // Airy 1830 semi-minor axis double b = 6356256.909; // Airy 1830 semi-minor axis
double f0 = 0.9996012717; // National Grid point scale factor on the central meridian double f0 = 0.9996012717; // National Grid point scale factor on the central meridian
@@ -419,12 +419,12 @@ float GeoCoord::rangeRadiansToMeters(double range_radians) {
} }
// Find distance from point to passed in point // Find distance from point to passed in point
int32_t GeoCoord::distanceTo(GeoCoord pointB) { int32_t GeoCoord::distanceTo(const GeoCoord& pointB) {
return latLongToMeter(this->getLatitude() * 1e-7, this->getLongitude() * 1e-7, pointB.getLatitude() * 1e-7, pointB.getLongitude() * 1e-7); return latLongToMeter(this->getLatitude() * 1e-7, this->getLongitude() * 1e-7, pointB.getLatitude() * 1e-7, pointB.getLongitude() * 1e-7);
} }
// Find bearing from point to passed in point // Find bearing from point to passed in point
int32_t GeoCoord::bearingTo(GeoCoord pointB) { int32_t GeoCoord::bearingTo(const GeoCoord& pointB) {
return bearing(this->getLatitude() * 1e-7, this->getLongitude() * 1e-7, pointB.getLatitude() * 1e-7, pointB.getLongitude() * 1e-7); return bearing(this->getLatitude() * 1e-7, this->getLongitude() * 1e-7, pointB.getLatitude() * 1e-7, pointB.getLongitude() * 1e-7);
} }
@@ -447,4 +447,4 @@ std::shared_ptr<GeoCoord> GeoCoord::pointAtDistance(double bearing, double range
return std::make_shared<GeoCoord>(double(lat), double(lon), this->getAltitude()); return std::make_shared<GeoCoord>(double(lat), double(lon), this->getAltitude());
} }

View File

@@ -86,11 +86,11 @@ class GeoCoord {
int32_t _longitude = 0; int32_t _longitude = 0;
int32_t _altitude = 0; int32_t _altitude = 0;
DMS _dms; DMS _dms = {};
UTM _utm; UTM _utm = {};
MGRS _mgrs; MGRS _mgrs = {};
OSGR _osgr; OSGR _osgr = {};
OLC _olc; OLC _olc = {};
bool _dirty = true; bool _dirty = true;
@@ -119,8 +119,8 @@ class GeoCoord {
static float rangeMetersToRadians(double range_meters); static float rangeMetersToRadians(double range_meters);
// Point to point conversions // Point to point conversions
int32_t distanceTo(GeoCoord pointB); int32_t distanceTo(const GeoCoord& pointB);
int32_t bearingTo(GeoCoord pointB); int32_t bearingTo(const GeoCoord& pointB);
std::shared_ptr<GeoCoord> pointAtDistance(double bearing, double range); std::shared_ptr<GeoCoord> pointAtDistance(double bearing, double range);
// Lat lon alt getters // Lat lon alt getters

View File

@@ -23,14 +23,14 @@ class NMEAGPS : public GPS
#endif #endif
public: public:
virtual bool setupGPS(); virtual bool setupGPS() override;
protected: protected:
/** Subclasses should look for serial rx characters here and feed it to their GPS parser /** Subclasses should look for serial rx characters here and feed it to their GPS parser
* *
* Return true if we received a valid message from the GPS * Return true if we received a valid message from the GPS
*/ */
virtual bool whileIdle(); virtual bool whileIdle() override;
/** /**
* Perform any processing that should be done only while the GPS is awake and looking for a fix. * Perform any processing that should be done only while the GPS is awake and looking for a fix.
@@ -38,7 +38,7 @@ class NMEAGPS : public GPS
* *
* @return true if we've acquired a time * @return true if we've acquired a time
*/ */
virtual bool lookForTime(); virtual bool lookForTime() override;
/** /**
* Perform any processing that should be done only while the GPS is awake and looking for a fix. * Perform any processing that should be done only while the GPS is awake and looking for a fix.
@@ -46,7 +46,7 @@ class NMEAGPS : public GPS
* *
* @return true if we've acquired a new location * @return true if we've acquired a new location
*/ */
virtual bool lookForLocation(); virtual bool lookForLocation() override;
virtual bool hasLock(); virtual bool hasLock() override;
}; };

View File

@@ -22,22 +22,22 @@ class UBloxGPS : public GPS
* *
* @return true for success * @return true for success
*/ */
bool factoryReset(); bool factoryReset() override;
protected: protected:
/** /**
* Returns true if we succeeded * Returns true if we succeeded
*/ */
virtual bool setupGPS(); virtual bool setupGPS() override;
/** Subclasses should look for serial rx characters here and feed it to their GPS parser /** Subclasses should look for serial rx characters here and feed it to their GPS parser
* *
* Return true if we received a valid message from the GPS * Return true if we received a valid message from the GPS
*/ */
virtual bool whileIdle(); virtual bool whileIdle() override;
/** Idle processing while GPS is looking for lock */ /** Idle processing while GPS is looking for lock */
virtual void whileActive(); virtual void whileActive() override;
/** /**
* Perform any processing that should be done only while the GPS is awake and looking for a fix. * Perform any processing that should be done only while the GPS is awake and looking for a fix.
@@ -45,7 +45,7 @@ class UBloxGPS : public GPS
* *
* @return true if we've acquired a time * @return true if we've acquired a time
*/ */
virtual bool lookForTime(); virtual bool lookForTime() override;
/** /**
* Perform any processing that should be done only while the GPS is awake and looking for a fix. * Perform any processing that should be done only while the GPS is awake and looking for a fix.
@@ -53,12 +53,12 @@ class UBloxGPS : public GPS
* *
* @return true if we've acquired a new location * @return true if we've acquired a new location
*/ */
virtual bool lookForLocation(); virtual bool lookForLocation() override;
virtual bool hasLock(); virtual bool hasLock() override;
/// If possible force the GPS into sleep/low power mode /// If possible force the GPS into sleep/low power mode
virtual void sleep(); virtual void sleep() override;
virtual void wake(); virtual void wake() override;
private: private:
/// Attempt to connect to our GPS, returns false if no gps is present /// Attempt to connect to our GPS, returns false if no gps is present

View File

@@ -25,7 +25,7 @@ class EInkDisplay : public OLEDDisplay
EInkDisplay(uint8_t address, int sda, int scl); EInkDisplay(uint8_t address, int sda, int scl);
// Write the buffer to the display memory (for eink we only do this occasionally) // Write the buffer to the display memory (for eink we only do this occasionally)
virtual void display(void); virtual void display(void) override;
/** /**
* Force a display update if we haven't drawn within the specified msecLimit * Force a display update if we haven't drawn within the specified msecLimit
@@ -36,13 +36,13 @@ class EInkDisplay : public OLEDDisplay
protected: protected:
// the header size of the buffer used, e.g. for the SPI command header // the header size of the buffer used, e.g. for the SPI command header
virtual int getBufferOffset(void) { return 0; } virtual int getBufferOffset(void) override { return 0; }
// Send a command to the display (low level function) // Send a command to the display (low level function)
virtual void sendCommand(uint8_t com); virtual void sendCommand(uint8_t com) override;
// Connect to the display // Connect to the display
virtual bool connect(); virtual bool connect() override;
}; };

View File

@@ -26,7 +26,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "MeshService.h" #include "MeshService.h"
#include "NodeDB.h" #include "NodeDB.h"
#include "Screen.h" #include "Screen.h"
#include "fonts.h"
#include "gps/GeoCoord.h" #include "gps/GeoCoord.h"
#include "gps/RTC.h" #include "gps/RTC.h"
#include "graphics/images.h" #include "graphics/images.h"
@@ -219,6 +218,14 @@ static void drawFrameBluetooth(OLEDDisplay *display, OLEDDisplayUiState *state,
display->drawString(64 + x, 48 + y, buf); display->drawString(64 + x, 48 + y, buf);
} }
static void drawFrameShutdown(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, "Shutting down...");
}
static void drawFrameFirmware(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) static void drawFrameFirmware(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{ {
display->setTextAlignment(TEXT_ALIGN_CENTER); display->setTextAlignment(TEXT_ALIGN_CENTER);
@@ -442,10 +449,10 @@ static void drawGPScoordinates(OLEDDisplay *display, int16_t x, int16_t y, const
if (gpsFormat == GpsCoordinateFormat_GpsFormatDec) { // Decimal Degrees if (gpsFormat == GpsCoordinateFormat_GpsFormatDec) { // Decimal Degrees
sprintf(coordinateLine, "%f %f", geoCoord.getLatitude() * 1e-7, geoCoord.getLongitude() * 1e-7); sprintf(coordinateLine, "%f %f", geoCoord.getLatitude() * 1e-7, geoCoord.getLongitude() * 1e-7);
} else if (gpsFormat == GpsCoordinateFormat_GpsFormatUTM) { // Universal Transverse Mercator } else if (gpsFormat == GpsCoordinateFormat_GpsFormatUTM) { // Universal Transverse Mercator
sprintf(coordinateLine, "%2i%1c %06i %07i", geoCoord.getUTMZone(), geoCoord.getUTMBand(), sprintf(coordinateLine, "%2i%1c %06u %07u", geoCoord.getUTMZone(), geoCoord.getUTMBand(),
geoCoord.getUTMEasting(), geoCoord.getUTMNorthing()); geoCoord.getUTMEasting(), geoCoord.getUTMNorthing());
} else if (gpsFormat == GpsCoordinateFormat_GpsFormatMGRS) { // Military Grid Reference System } else if (gpsFormat == GpsCoordinateFormat_GpsFormatMGRS) { // Military Grid Reference System
sprintf(coordinateLine, "%2i%1c %1c%1c %05i %05i", geoCoord.getMGRSZone(), geoCoord.getMGRSBand(), sprintf(coordinateLine, "%2i%1c %1c%1c %05u %05u", geoCoord.getMGRSZone(), geoCoord.getMGRSBand(),
geoCoord.getMGRSEast100k(), geoCoord.getMGRSNorth100k(), geoCoord.getMGRSEasting(), geoCoord.getMGRSEast100k(), geoCoord.getMGRSNorth100k(), geoCoord.getMGRSEasting(),
geoCoord.getMGRSNorthing()); geoCoord.getMGRSNorthing());
} else if (gpsFormat == GpsCoordinateFormat_GpsFormatOLC) { // Open Location Code } else if (gpsFormat == GpsCoordinateFormat_GpsFormatOLC) { // Open Location Code
@@ -454,7 +461,7 @@ static void drawGPScoordinates(OLEDDisplay *display, int16_t x, int16_t y, const
if (geoCoord.getOSGRE100k() == 'I' || geoCoord.getOSGRN100k() == 'I') // OSGR is only valid around the UK region if (geoCoord.getOSGRE100k() == 'I' || geoCoord.getOSGRN100k() == 'I') // OSGR is only valid around the UK region
sprintf(coordinateLine, "%s", "Out of Boundary"); sprintf(coordinateLine, "%s", "Out of Boundary");
else else
sprintf(coordinateLine, "%1c%1c %05i %05i", geoCoord.getOSGRE100k(), geoCoord.getOSGRN100k(), sprintf(coordinateLine, "%1c%1c %05u %05u", geoCoord.getOSGRE100k(), geoCoord.getOSGRN100k(),
geoCoord.getOSGREasting(), geoCoord.getOSGRNorthing()); geoCoord.getOSGREasting(), geoCoord.getOSGRNorthing());
} }
@@ -472,9 +479,9 @@ static void drawGPScoordinates(OLEDDisplay *display, int16_t x, int16_t y, const
} else { } else {
char latLine[22]; char latLine[22];
char lonLine[22]; char lonLine[22];
sprintf(latLine, "%2i° %2i' %2.4f\" %1c", geoCoord.getDMSLatDeg(), geoCoord.getDMSLatMin(), geoCoord.getDMSLatSec(), sprintf(latLine, "%2i° %2i' %2u\" %1c", geoCoord.getDMSLatDeg(), geoCoord.getDMSLatMin(), geoCoord.getDMSLatSec(),
geoCoord.getDMSLatCP()); geoCoord.getDMSLatCP());
sprintf(lonLine, "%3i° %2i' %2.4f\" %1c", geoCoord.getDMSLonDeg(), geoCoord.getDMSLonMin(), geoCoord.getDMSLonSec(), sprintf(lonLine, "%3i° %2i' %2u\" %1c", geoCoord.getDMSLonDeg(), geoCoord.getDMSLonMin(), geoCoord.getDMSLonSec(),
geoCoord.getDMSLonCP()); geoCoord.getDMSLonCP());
display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(latLine))) / 2, y - FONT_HEIGHT_SMALL * 1, latLine); display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(latLine))) / 2, y - FONT_HEIGHT_SMALL * 1, latLine);
display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(lonLine))) / 2, y, lonLine); display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(lonLine))) / 2, y, lonLine);
@@ -644,7 +651,6 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
static char distStr[20]; static char distStr[20];
strcpy(distStr, "? km"); // might not have location data strcpy(distStr, "? km"); // might not have location data
float headingRadian;
NodeInfo *ourNode = nodeDB.getNode(nodeDB.getNodeNum()); NodeInfo *ourNode = nodeDB.getNode(nodeDB.getNodeNum());
const char *fields[] = {username, distStr, signalStr, lastStr, NULL}; const char *fields[] = {username, distStr, signalStr, lastStr, NULL};
@@ -672,7 +678,7 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
// it. currently we don't do this and instead draw north up only. // it. currently we don't do this and instead draw north up only.
float bearingToOther = float bearingToOther =
GeoCoord::bearing(DegD(p.latitude_i), DegD(p.longitude_i), DegD(op.latitude_i), DegD(op.longitude_i)); GeoCoord::bearing(DegD(p.latitude_i), DegD(p.longitude_i), DegD(op.latitude_i), DegD(op.longitude_i));
headingRadian = bearingToOther - myHeading; float headingRadian = bearingToOther - myHeading;
drawNodeHeading(display, compassX, compassY, headingRadian); drawNodeHeading(display, compassX, compassY, headingRadian);
} }
} }
@@ -820,6 +826,9 @@ void Screen::setup()
nodeStatusObserver.observe(&nodeStatus->onNewStatus); nodeStatusObserver.observe(&nodeStatus->onNewStatus);
if (textMessagePlugin) if (textMessagePlugin)
textMessageObserver.observe(textMessagePlugin); textMessageObserver.observe(textMessagePlugin);
// Plugins can notify screen about refresh
MeshPlugin::observeUIEvents(&uiFrameEventObserver);
} }
void Screen::forceDisplay() void Screen::forceDisplay()
@@ -878,6 +887,9 @@ int32_t Screen::runOnce()
handlePrint(cmd.print_text); handlePrint(cmd.print_text);
free(cmd.print_text); free(cmd.print_text);
break; break;
case Cmd::START_SHUTDOWN_SCREEN:
handleShutdownScreen();
break;
default: default:
DEBUG_MSG("BUG: invalid cmd\n"); DEBUG_MSG("BUG: invalid cmd\n");
} }
@@ -930,20 +942,20 @@ int32_t Screen::runOnce()
void Screen::drawDebugInfoTrampoline(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) void Screen::drawDebugInfoTrampoline(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{ {
Screen *screen = reinterpret_cast<Screen *>(state->userData); Screen *screen2 = reinterpret_cast<Screen *>(state->userData);
screen->debugInfo.drawFrame(display, state, x, y); screen2->debugInfo.drawFrame(display, state, x, y);
} }
void Screen::drawDebugInfoSettingsTrampoline(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) void Screen::drawDebugInfoSettingsTrampoline(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{ {
Screen *screen = reinterpret_cast<Screen *>(state->userData); Screen *screen2 = reinterpret_cast<Screen *>(state->userData);
screen->debugInfo.drawFrameSettings(display, state, x, y); screen2->debugInfo.drawFrameSettings(display, state, x, y);
} }
void Screen::drawDebugInfoWiFiTrampoline(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) void Screen::drawDebugInfoWiFiTrampoline(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{ {
Screen *screen = reinterpret_cast<Screen *>(state->userData); Screen *screen2 = reinterpret_cast<Screen *>(state->userData);
screen->debugInfo.drawFrameWiFi(display, state, x, y); screen2->debugInfo.drawFrameWiFi(display, state, x, y);
} }
/* show a message that the SSL cert is being built /* show a message that the SSL cert is being built
@@ -1037,13 +1049,25 @@ void Screen::handleStartBluetoothPinScreen(uint32_t pin)
static FrameCallback btFrames[] = {drawFrameBluetooth}; static FrameCallback btFrames[] = {drawFrameBluetooth};
snprintf(btPIN, sizeof(btPIN), "%06lu", pin); snprintf(btPIN, sizeof(btPIN), "%06u", pin);
ui.disableAllIndicators(); ui.disableAllIndicators();
ui.setFrames(btFrames, 1); ui.setFrames(btFrames, 1);
setFastFramerate(); setFastFramerate();
} }
void Screen::handleShutdownScreen()
{
DEBUG_MSG("showing shutdown screen\n");
showingNormalScreen = false;
static FrameCallback shutdownFrames[] = {drawFrameShutdown};
ui.disableAllIndicators();
ui.setFrames(shutdownFrames, 1);
setFastFramerate();
}
void Screen::handleStartFirmwareUpdateScreen() void Screen::handleStartFirmwareUpdateScreen()
{ {
DEBUG_MSG("showing firmware screen\n"); DEBUG_MSG("showing firmware screen\n");
@@ -1457,4 +1481,23 @@ int Screen::handleTextMessage(const MeshPacket *packet)
return 0; return 0;
} }
int Screen::handleUIFrameEvent(const UIFrameEvent *event)
{
if (showingNormalScreen) {
if (event->frameChanged)
{
setFrames(); // Regen the list of screens (will show new text message)
}
else if (event->needRedraw)
{
setFastFramerate();
// TODO: We might also want switch to corresponding frame,
// but we don't know the exact frame number.
//ui.switchToFrame(0);
}
}
return 0;
}
} // namespace graphics } // namespace graphics

View File

@@ -40,6 +40,7 @@ class Screen
#include "concurrency/OSThread.h" #include "concurrency/OSThread.h"
#include "power.h" #include "power.h"
#include <string> #include <string>
#include "mesh/MeshPlugin.h"
// 0 to 255, though particular variants might define different defaults // 0 to 255, though particular variants might define different defaults
#ifndef BRIGHTNESS_DEFAULT #ifndef BRIGHTNESS_DEFAULT
@@ -90,9 +91,11 @@ class Screen : public concurrency::OSThread
CallbackObserver<Screen, const meshtastic::Status *>(this, &Screen::handleStatusUpdate); CallbackObserver<Screen, const meshtastic::Status *>(this, &Screen::handleStatusUpdate);
CallbackObserver<Screen, const MeshPacket *> textMessageObserver = CallbackObserver<Screen, const MeshPacket *> textMessageObserver =
CallbackObserver<Screen, const MeshPacket *>(this, &Screen::handleTextMessage); CallbackObserver<Screen, const MeshPacket *>(this, &Screen::handleTextMessage);
CallbackObserver<Screen, const UIFrameEvent *> uiFrameEventObserver =
CallbackObserver<Screen, const UIFrameEvent *>(this, &Screen::handleUIFrameEvent);
public: public:
Screen(uint8_t address, int sda = -1, int scl = -1); explicit Screen(uint8_t address, int sda = -1, int scl = -1);
Screen(const Screen &) = delete; Screen(const Screen &) = delete;
Screen &operator=(const Screen &) = delete; Screen &operator=(const Screen &) = delete;
@@ -148,6 +151,12 @@ class Screen : public concurrency::OSThread
enqueueCmd(cmd); enqueueCmd(cmd);
} }
void startShutdownScreen()
{
ScreenCmd cmd;
cmd.cmd = Cmd::START_SHUTDOWN_SCREEN;
enqueueCmd(cmd);
}
/// Stops showing the bluetooth PIN screen. /// Stops showing the bluetooth PIN screen.
void stopBluetoothPinScreen() { enqueueCmd(ScreenCmd{.cmd = Cmd::STOP_BLUETOOTH_PIN_SCREEN}); } void stopBluetoothPinScreen() { enqueueCmd(ScreenCmd{.cmd = Cmd::STOP_BLUETOOTH_PIN_SCREEN}); }
@@ -218,6 +227,7 @@ class Screen : public concurrency::OSThread
int handleStatusUpdate(const meshtastic::Status *arg); int handleStatusUpdate(const meshtastic::Status *arg);
int handleTextMessage(const MeshPacket *arg); int handleTextMessage(const MeshPacket *arg);
int handleUIFrameEvent(const UIFrameEvent *arg);
/// Used to force (super slow) eink displays to draw critical frames /// Used to force (super slow) eink displays to draw critical frames
void forceDisplay(); void forceDisplay();
@@ -258,7 +268,7 @@ class Screen : public concurrency::OSThread
void handleStartBluetoothPinScreen(uint32_t pin); void handleStartBluetoothPinScreen(uint32_t pin);
void handlePrint(const char *text); void handlePrint(const char *text);
void handleStartFirmwareUpdateScreen(); void handleStartFirmwareUpdateScreen();
void handleShutdownScreen();
/// Rebuilds our list of frames (screens) to default ones. /// Rebuilds our list of frames (screens) to default ones.
void setFrames(); void setFrames();
@@ -303,4 +313,4 @@ class Screen : public concurrency::OSThread
}; };
} // namespace graphics } // namespace graphics
#endif #endif

View File

@@ -21,15 +21,15 @@ class TFTDisplay : public OLEDDisplay
TFTDisplay(uint8_t address, int sda, int scl); TFTDisplay(uint8_t address, int sda, int scl);
// Write the buffer to the display memory // Write the buffer to the display memory
virtual void display(void); virtual void display(void) override;
protected: protected:
// the header size of the buffer used, e.g. for the SPI command header // the header size of the buffer used, e.g. for the SPI command header
virtual int getBufferOffset(void) { return 0; } virtual int getBufferOffset(void) override { return 0; }
// Send a command to the display (low level function) // Send a command to the display (low level function)
virtual void sendCommand(uint8_t com); virtual void sendCommand(uint8_t com) override;
// Connect to the display // Connect to the display
virtual bool connect(); virtual bool connect() override;
}; };

View File

@@ -1,425 +0,0 @@
#pragma once
const uint8_t Custom_ArialMT_Plain_10[] PROGMEM = {
0x0A, // Width: 10
0x0A, // Height: 10
0x20, // First Char: 32
0xE0, // Numbers of Chars: 224
// Jump Table:
0xFF, 0xFF, 0x00, 0x03, // 32:65535
0x00, 0x00, 0x04, 0x03, // 33:0
0x00, 0x04, 0x05, 0x04, // 34:4
0x00, 0x09, 0x09, 0x06, // 35:9
0x00, 0x12, 0x0A, 0x06, // 36:18
0x00, 0x1C, 0x10, 0x09, // 37:28
0x00, 0x2C, 0x0E, 0x07, // 38:44
0x00, 0x3A, 0x01, 0x02, // 39:58
0x00, 0x3B, 0x06, 0x03, // 40:59
0x00, 0x41, 0x06, 0x03, // 41:65
0x00, 0x47, 0x05, 0x04, // 42:71
0x00, 0x4C, 0x09, 0x06, // 43:76
0x00, 0x55, 0x04, 0x03, // 44:85
0x00, 0x59, 0x03, 0x03, // 45:89
0x00, 0x5C, 0x04, 0x03, // 46:92
0x00, 0x60, 0x05, 0x03, // 47:96
0x00, 0x65, 0x0A, 0x06, // 48:101
0x00, 0x6F, 0x08, 0x06, // 49:111
0x00, 0x77, 0x0A, 0x06, // 50:119
0x00, 0x81, 0x0A, 0x06, // 51:129
0x00, 0x8B, 0x0B, 0x06, // 52:139
0x00, 0x96, 0x0A, 0x06, // 53:150
0x00, 0xA0, 0x0A, 0x06, // 54:160
0x00, 0xAA, 0x09, 0x06, // 55:170
0x00, 0xB3, 0x0A, 0x06, // 56:179
0x00, 0xBD, 0x0A, 0x06, // 57:189
0x00, 0xC7, 0x04, 0x03, // 58:199
0x00, 0xCB, 0x04, 0x03, // 59:203
0x00, 0xCF, 0x0A, 0x06, // 60:207
0x00, 0xD9, 0x09, 0x06, // 61:217
0x00, 0xE2, 0x09, 0x06, // 62:226
0x00, 0xEB, 0x0B, 0x06, // 63:235
0x00, 0xF6, 0x14, 0x0A, // 64:246
0x01, 0x0A, 0x0E, 0x07, // 65:266
0x01, 0x18, 0x0C, 0x07, // 66:280
0x01, 0x24, 0x0C, 0x07, // 67:292
0x01, 0x30, 0x0B, 0x07, // 68:304
0x01, 0x3B, 0x0C, 0x07, // 69:315
0x01, 0x47, 0x09, 0x06, // 70:327
0x01, 0x50, 0x0D, 0x08, // 71:336
0x01, 0x5D, 0x0C, 0x07, // 72:349
0x01, 0x69, 0x04, 0x03, // 73:361
0x01, 0x6D, 0x08, 0x05, // 74:365
0x01, 0x75, 0x0E, 0x07, // 75:373
0x01, 0x83, 0x0C, 0x06, // 76:387
0x01, 0x8F, 0x10, 0x08, // 77:399
0x01, 0x9F, 0x0C, 0x07, // 78:415
0x01, 0xAB, 0x0E, 0x08, // 79:427
0x01, 0xB9, 0x0B, 0x07, // 80:441
0x01, 0xC4, 0x0E, 0x08, // 81:452
0x01, 0xD2, 0x0C, 0x07, // 82:466
0x01, 0xDE, 0x0C, 0x07, // 83:478
0x01, 0xEA, 0x0B, 0x06, // 84:490
0x01, 0xF5, 0x0C, 0x07, // 85:501
0x02, 0x01, 0x0D, 0x07, // 86:513
0x02, 0x0E, 0x11, 0x09, // 87:526
0x02, 0x1F, 0x0E, 0x07, // 88:543
0x02, 0x2D, 0x0D, 0x07, // 89:557
0x02, 0x3A, 0x0C, 0x06, // 90:570
0x02, 0x46, 0x06, 0x03, // 91:582
0x02, 0x4C, 0x06, 0x03, // 92:588
0x02, 0x52, 0x04, 0x03, // 93:594
0x02, 0x56, 0x09, 0x05, // 94:598
0x02, 0x5F, 0x0C, 0x06, // 95:607
0x02, 0x6B, 0x03, 0x03, // 96:619
0x02, 0x6E, 0x0A, 0x06, // 97:622
0x02, 0x78, 0x0A, 0x06, // 98:632
0x02, 0x82, 0x0A, 0x05, // 99:642
0x02, 0x8C, 0x0A, 0x06, // 100:652
0x02, 0x96, 0x0A, 0x06, // 101:662
0x02, 0xA0, 0x05, 0x03, // 102:672
0x02, 0xA5, 0x0A, 0x06, // 103:677
0x02, 0xAF, 0x0A, 0x06, // 104:687
0x02, 0xB9, 0x04, 0x02, // 105:697
0x02, 0xBD, 0x04, 0x02, // 106:701
0x02, 0xC1, 0x08, 0x05, // 107:705
0x02, 0xC9, 0x04, 0x02, // 108:713
0x02, 0xCD, 0x10, 0x08, // 109:717
0x02, 0xDD, 0x0A, 0x06, // 110:733
0x02, 0xE7, 0x0A, 0x06, // 111:743
0x02, 0xF1, 0x0A, 0x06, // 112:753
0x02, 0xFB, 0x0A, 0x06, // 113:763
0x03, 0x05, 0x05, 0x03, // 114:773
0x03, 0x0A, 0x08, 0x05, // 115:778
0x03, 0x12, 0x06, 0x03, // 116:786
0x03, 0x18, 0x0A, 0x06, // 117:792
0x03, 0x22, 0x09, 0x05, // 118:802
0x03, 0x2B, 0x0E, 0x07, // 119:811
0x03, 0x39, 0x0A, 0x05, // 120:825
0x03, 0x43, 0x09, 0x05, // 121:835
0x03, 0x4C, 0x0A, 0x05, // 122:844
0x03, 0x56, 0x06, 0x03, // 123:854
0x03, 0x5C, 0x04, 0x03, // 124:860
0x03, 0x60, 0x05, 0x03, // 125:864
0x03, 0x65, 0x09, 0x06, // 126:869
0xFF, 0xFF, 0x00, 0x00, // 127:65535
0xFF, 0xFF, 0x00, 0x0A, // 128:65535
0xFF, 0xFF, 0x00, 0x0A, // 129:65535
0xFF, 0xFF, 0x00, 0x0A, // 130:65535
0xFF, 0xFF, 0x00, 0x0A, // 131:65535
0xFF, 0xFF, 0x00, 0x0A, // 132:65535
0xFF, 0xFF, 0x00, 0x0A, // 133:65535
0xFF, 0xFF, 0x00, 0x0A, // 134:65535
0xFF, 0xFF, 0x00, 0x0A, // 135:65535
0xFF, 0xFF, 0x00, 0x0A, // 136:65535
0xFF, 0xFF, 0x00, 0x0A, // 137:65535
0xFF, 0xFF, 0x00, 0x0A, // 138:65535
0xFF, 0xFF, 0x00, 0x0A, // 139:65535
0xFF, 0xFF, 0x00, 0x0A, // 140:65535
0xFF, 0xFF, 0x00, 0x0A, // 141:65535
0xFF, 0xFF, 0x00, 0x0A, // 142:65535
0xFF, 0xFF, 0x00, 0x0A, // 143:65535
0xFF, 0xFF, 0x00, 0x0A, // 144:65535
0xFF, 0xFF, 0x00, 0x0A, // 145:65535
0xFF, 0xFF, 0x00, 0x0A, // 146:65535
0xFF, 0xFF, 0x00, 0x0A, // 147:65535
0xFF, 0xFF, 0x00, 0x0A, // 148:65535
0xFF, 0xFF, 0x00, 0x0A, // 149:65535
0xFF, 0xFF, 0x00, 0x0A, // 150:65535
0xFF, 0xFF, 0x00, 0x0A, // 151:65535
0xFF, 0xFF, 0x00, 0x0A, // 152:65535
0xFF, 0xFF, 0x00, 0x0A, // 153:65535
0xFF, 0xFF, 0x00, 0x0A, // 154:65535
0xFF, 0xFF, 0x00, 0x0A, // 155:65535
0xFF, 0xFF, 0x00, 0x0A, // 156:65535
0xFF, 0xFF, 0x00, 0x0A, // 157:65535
0xFF, 0xFF, 0x00, 0x0A, // 158:65535
0xFF, 0xFF, 0x00, 0x0A, // 159:65535
0xFF, 0xFF, 0x00, 0x03, // 160:65535
0x03, 0x6E, 0x04, 0x03, // 161:878
0x03, 0x72, 0x0A, 0x06, // 162:882
0x03, 0x7C, 0x0C, 0x06, // 163:892
0x03, 0x88, 0x0A, 0x06, // 164:904
0x03, 0x92, 0x0A, 0x06, // 165:914
0x03, 0x9C, 0x04, 0x03, // 166:924
0x03, 0xA0, 0x0A, 0x06, // 167:928
0x03, 0xAA, 0x05, 0x03, // 168:938
0x03, 0xAF, 0x0D, 0x07, // 169:943
0x03, 0xBC, 0x07, 0x04, // 170:956
0x03, 0xC3, 0x0A, 0x06, // 171:963
0x03, 0xCD, 0x09, 0x06, // 172:973
0x03, 0xD6, 0x03, 0x03, // 173:982
0x03, 0xD9, 0x0D, 0x07, // 174:985
0x03, 0xE6, 0x0B, 0x06, // 175:998
0x03, 0xF1, 0x07, 0x04, // 176:1009
0x03, 0xF8, 0x0A, 0x05, // 177:1016
0x04, 0x02, 0x05, 0x03, // 178:1026
0x04, 0x07, 0x05, 0x03, // 179:1031
0x04, 0x0C, 0x05, 0x03, // 180:1036
0x04, 0x11, 0x0A, 0x06, // 181:1041
0x04, 0x1B, 0x09, 0x05, // 182:1051
0x04, 0x24, 0x03, 0x03, // 183:1060
0x04, 0x27, 0x06, 0x03, // 184:1063
0x04, 0x2D, 0x05, 0x03, // 185:1069
0x04, 0x32, 0x07, 0x04, // 186:1074
0x04, 0x39, 0x0A, 0x06, // 187:1081
0x04, 0x43, 0x10, 0x08, // 188:1091
0x04, 0x53, 0x10, 0x08, // 189:1107
0x04, 0x63, 0x10, 0x08, // 190:1123
0x04, 0x73, 0x0A, 0x06, // 191:1139
0x04, 0x7D, 0x0E, 0x07, // 192:1149
0x04, 0x8B, 0x0E, 0x07, // 193:1163
0x04, 0x99, 0x0E, 0x07, // 194:1177
0x04, 0xA7, 0x0E, 0x07, // 195:1191
0x04, 0xB5, 0x0E, 0x07, // 196:1205
0x04, 0xC3, 0x0E, 0x07, // 197:1219
0x04, 0xD1, 0x12, 0x0A, // 198:1233
0x04, 0xE3, 0x0C, 0x07, // 199:1251
0x04, 0xEF, 0x0C, 0x07, // 200:1263
0x04, 0xFB, 0x0C, 0x07, // 201:1275
0x05, 0x07, 0x0C, 0x07, // 202:1287
0x05, 0x13, 0x0C, 0x07, // 203:1299
0x05, 0x1F, 0x05, 0x03, // 204:1311
0x05, 0x24, 0x04, 0x03, // 205:1316
0x05, 0x28, 0x04, 0x03, // 206:1320
0x05, 0x2C, 0x05, 0x03, // 207:1324
0x05, 0x31, 0x0B, 0x07, // 208:1329
0x05, 0x3C, 0x0C, 0x07, // 209:1340
0x05, 0x48, 0x0E, 0x08, // 210:1352
0x05, 0x56, 0x0E, 0x08, // 211:1366
0x05, 0x64, 0x0E, 0x08, // 212:1380
0x05, 0x72, 0x0E, 0x08, // 213:1394
0x05, 0x80, 0x0E, 0x08, // 214:1408
0x05, 0x8E, 0x0A, 0x06, // 215:1422
0x05, 0x98, 0x0D, 0x08, // 216:1432
0x05, 0xA5, 0x0C, 0x07, // 217:1445
0x05, 0xB1, 0x0C, 0x07, // 218:1457
0x05, 0xBD, 0x0C, 0x07, // 219:1469
0x05, 0xC9, 0x0C, 0x07, // 220:1481
0x05, 0xD5, 0x0D, 0x07, // 221:1493
0x05, 0xE2, 0x0B, 0x07, // 222:1506
0x05, 0xED, 0x0C, 0x06, // 223:1517
0x05, 0xF9, 0x0A, 0x06, // 224:1529
0x06, 0x03, 0x0A, 0x06, // 225:1539
0x06, 0x0D, 0x0A, 0x06, // 226:1549
0x06, 0x17, 0x0A, 0x06, // 227:1559
0x06, 0x21, 0x0A, 0x06, // 228:1569
0x06, 0x2B, 0x0A, 0x06, // 229:1579
0x06, 0x35, 0x10, 0x09, // 230:1589
0x06, 0x45, 0x0A, 0x05, // 231:1605
0x06, 0x4F, 0x0A, 0x06, // 232:1615
0x06, 0x59, 0x0A, 0x06, // 233:1625
0x06, 0x63, 0x0A, 0x06, // 234:1635
0x06, 0x6D, 0x0A, 0x06, // 235:1645
0x06, 0x77, 0x05, 0x03, // 236:1655
0x06, 0x7C, 0x04, 0x03, // 237:1660
0x06, 0x80, 0x05, 0x03, // 238:1664
0x06, 0x85, 0x05, 0x03, // 239:1669
0x06, 0x8A, 0x0A, 0x06, // 240:1674
0x06, 0x94, 0x0A, 0x06, // 241:1684
0x06, 0x9E, 0x0A, 0x06, // 242:1694
0x06, 0xA8, 0x0A, 0x06, // 243:1704
0x06, 0xB2, 0x0A, 0x06, // 244:1714
0x06, 0xBC, 0x0A, 0x06, // 245:1724
0x06, 0xC6, 0x0A, 0x06, // 246:1734
0x06, 0xD0, 0x09, 0x05, // 247:1744
0x06, 0xD9, 0x0A, 0x06, // 248:1753
0x06, 0xE3, 0x0A, 0x06, // 249:1763
0x06, 0xED, 0x0A, 0x06, // 250:1773
0x06, 0xF7, 0x0A, 0x06, // 251:1783
0x07, 0x01, 0x0A, 0x06, // 252:1793
0x07, 0x0B, 0x09, 0x05, // 253:1803
0x07, 0x14, 0x0A, 0x06, // 254:1812
0x07, 0x1E, 0x09, 0x05, // 255:1822
// 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
0x08, 0x00, 0x00, 0x00, 0x08, // 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, 0x00, 0x14, 0x00, 0x18, // 184
0x00, 0x00, 0x10, 0x00, 0x78, // 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, 0x02, 0xC0, 0x01, 0xB0, 0x00, 0x89, 0x00, 0xB2, 0x00, 0xC0, 0x01, 0x00, 0x02, // 192
0x00, 0x02, 0xC0, 0x01, 0xB0, 0x00, 0x8A, 0x00, 0xB1, 0x00, 0xC0, 0x01, 0x00, 0x02, // 193
0x00, 0x02, 0xC0, 0x01, 0xB2, 0x00, 0x89, 0x00, 0xB2, 0x00, 0xC0, 0x01, 0x00, 0x02, // 194
0x00, 0x02, 0xC2, 0x01, 0xB1, 0x00, 0x8A, 0x00, 0xB1, 0x00, 0xC0, 0x01, 0x00, 0x02, // 195
0x00, 0x02, 0xC0, 0x01, 0xB2, 0x00, 0x88, 0x00, 0xB2, 0x00, 0xC0, 0x01, 0x00, 0x02, // 196
0x00, 0x02, 0xC0, 0x01, 0xBE, 0x00, 0x8A, 0x00, 0xBE, 0x00, 0xC0, 0x01, 0x00, 0x02, // 197
0x00, 0x03, 0xC0, 0x00, 0xE0, 0x00, 0x98, 0x00, 0x88, 0x00, 0xF8, 0x03, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, // 198
0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x08, 0x16, 0x08, 0x1A, 0x10, 0x01, // 199
0x00, 0x00, 0xF8, 0x03, 0x49, 0x02, 0x4A, 0x02, 0x48, 0x02, 0x48, 0x02, // 200
0x00, 0x00, 0xF8, 0x03, 0x48, 0x02, 0x4A, 0x02, 0x49, 0x02, 0x48, 0x02, // 201
0x00, 0x00, 0xFA, 0x03, 0x49, 0x02, 0x4A, 0x02, 0x48, 0x02, 0x48, 0x02, // 202
0x00, 0x00, 0xF8, 0x03, 0x4A, 0x02, 0x48, 0x02, 0x4A, 0x02, 0x48, 0x02, // 203
0x00, 0x00, 0xF9, 0x03, 0x02, // 204
0x02, 0x00, 0xF9, 0x03, // 205
0x01, 0x00, 0xFA, 0x03, // 206
0x02, 0x00, 0xF8, 0x03, 0x02, // 207
0x40, 0x00, 0xF8, 0x03, 0x48, 0x02, 0x48, 0x02, 0x10, 0x01, 0xE0, // 208
0x00, 0x00, 0xFA, 0x03, 0x31, 0x00, 0x42, 0x00, 0x81, 0x01, 0xF8, 0x03, // 209
0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x09, 0x02, 0x0A, 0x02, 0x08, 0x02, 0xF0, 0x01, // 210
0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x0A, 0x02, 0x09, 0x02, 0x08, 0x02, 0xF0, 0x01, // 211
0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x0A, 0x02, 0x09, 0x02, 0x0A, 0x02, 0xF0, 0x01, // 212
0x00, 0x00, 0xF0, 0x01, 0x0A, 0x02, 0x09, 0x02, 0x0A, 0x02, 0x09, 0x02, 0xF0, 0x01, // 213
0x00, 0x00, 0xF0, 0x01, 0x0A, 0x02, 0x08, 0x02, 0x0A, 0x02, 0x08, 0x02, 0xF0, 0x01, // 214
0x10, 0x01, 0xA0, 0x00, 0xE0, 0x00, 0xA0, 0x00, 0x10, 0x01, // 215
0x00, 0x00, 0xF0, 0x02, 0x08, 0x03, 0xC8, 0x02, 0x28, 0x02, 0x18, 0x03, 0xE8, // 216
0x00, 0x00, 0xF8, 0x01, 0x01, 0x02, 0x02, 0x02, 0x00, 0x02, 0xF8, 0x01, // 217
0x00, 0x00, 0xF8, 0x01, 0x02, 0x02, 0x01, 0x02, 0x00, 0x02, 0xF8, 0x01, // 218
0x00, 0x00, 0xF8, 0x01, 0x02, 0x02, 0x01, 0x02, 0x02, 0x02, 0xF8, 0x01, // 219
0x00, 0x00, 0xF8, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x02, 0xF8, 0x01, // 220
0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0xC2, 0x03, 0x21, 0x00, 0x10, 0x00, 0x08, // 221
0x00, 0x00, 0xF8, 0x03, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xE0, // 222
0x00, 0x00, 0xF0, 0x03, 0x08, 0x01, 0x48, 0x02, 0xB0, 0x02, 0x80, 0x01, // 223
0x00, 0x00, 0x00, 0x03, 0xA4, 0x02, 0xA8, 0x02, 0xE0, 0x03, // 224
0x00, 0x00, 0x00, 0x03, 0xA8, 0x02, 0xA4, 0x02, 0xE0, 0x03, // 225
0x00, 0x00, 0x00, 0x03, 0xA8, 0x02, 0xA4, 0x02, 0xE8, 0x03, // 226
0x00, 0x00, 0x08, 0x03, 0xA4, 0x02, 0xA8, 0x02, 0xE4, 0x03, // 227
0x00, 0x00, 0x00, 0x03, 0xA8, 0x02, 0xA0, 0x02, 0xE8, 0x03, // 228
0x00, 0x00, 0x00, 0x03, 0xAE, 0x02, 0xAA, 0x02, 0xEE, 0x03, // 229
0x00, 0x00, 0x40, 0x03, 0xA0, 0x02, 0xA0, 0x02, 0xC0, 0x01, 0xA0, 0x02, 0xA0, 0x02, 0xC0, 0x02, // 230
0x00, 0x00, 0xC0, 0x01, 0x20, 0x16, 0x20, 0x1A, 0x40, 0x01, // 231
0x00, 0x00, 0xC0, 0x01, 0xA4, 0x02, 0xA8, 0x02, 0xC0, 0x02, // 232
0x00, 0x00, 0xC0, 0x01, 0xA8, 0x02, 0xA4, 0x02, 0xC0, 0x02, // 233
0x00, 0x00, 0xC0, 0x01, 0xA8, 0x02, 0xA4, 0x02, 0xC8, 0x02, // 234
0x00, 0x00, 0xC0, 0x01, 0xA8, 0x02, 0xA0, 0x02, 0xC8, 0x02, // 235
0x00, 0x00, 0xE4, 0x03, 0x08, // 236
0x08, 0x00, 0xE4, 0x03, // 237
0x08, 0x00, 0xE4, 0x03, 0x08, // 238
0x08, 0x00, 0xE0, 0x03, 0x08, // 239
0x00, 0x00, 0xC0, 0x01, 0x28, 0x02, 0x38, 0x02, 0xE0, 0x01, // 240
0x00, 0x00, 0xE8, 0x03, 0x24, 0x00, 0x28, 0x00, 0xC4, 0x03, // 241
0x00, 0x00, 0xC0, 0x01, 0x24, 0x02, 0x28, 0x02, 0xC0, 0x01, // 242
0x00, 0x00, 0xC0, 0x01, 0x28, 0x02, 0x24, 0x02, 0xC0, 0x01, // 243
0x00, 0x00, 0xC0, 0x01, 0x28, 0x02, 0x24, 0x02, 0xC8, 0x01, // 244
0x00, 0x00, 0xC8, 0x01, 0x24, 0x02, 0x28, 0x02, 0xC4, 0x01, // 245
0x00, 0x00, 0xC0, 0x01, 0x28, 0x02, 0x20, 0x02, 0xC8, 0x01, // 246
0x40, 0x00, 0x40, 0x00, 0x50, 0x01, 0x40, 0x00, 0x40, // 247
0x00, 0x00, 0xC0, 0x02, 0xA0, 0x03, 0x60, 0x02, 0xA0, 0x01, // 248
0x00, 0x00, 0xE0, 0x01, 0x04, 0x02, 0x08, 0x02, 0xE0, 0x03, // 249
0x00, 0x00, 0xE0, 0x01, 0x08, 0x02, 0x04, 0x02, 0xE0, 0x03, // 250
0x00, 0x00, 0xE8, 0x01, 0x04, 0x02, 0x08, 0x02, 0xE0, 0x03, // 251
0x00, 0x00, 0xE0, 0x01, 0x08, 0x02, 0x00, 0x02, 0xE8, 0x03, // 252
0x20, 0x00, 0xC0, 0x09, 0x08, 0x06, 0xC4, 0x01, 0x20, // 253
0x00, 0x00, 0xF8, 0x0F, 0x20, 0x02, 0x20, 0x02, 0xC0, 0x01, // 254
0x20, 0x00, 0xC8, 0x09, 0x00, 0x06, 0xC8, 0x01, 0x20 // 255
};

18
src/input/InputBroker.cpp Normal file
View File

@@ -0,0 +1,18 @@
#include "InputBroker.h"
InputBroker *inputBroker;
InputBroker::InputBroker()
{
};
void InputBroker::registerSource(Observable<const InputEvent *> *source)
{
this->inputEventObserver.observe(source);
}
int InputBroker::handleInputEvent(const InputEvent *event)
{
this->notifyObservers(event);
return 0;
}

22
src/input/InputBroker.h Normal file
View File

@@ -0,0 +1,22 @@
#pragma once
#include "Observer.h"
typedef struct _InputEvent {
const char* source;
char inputEvent;
} InputEvent;
class InputBroker :
public Observable<const InputEvent *>
{
CallbackObserver<InputBroker, const InputEvent *> inputEventObserver =
CallbackObserver<InputBroker, const InputEvent *>(this, &InputBroker::handleInputEvent);
public:
InputBroker();
void registerSource(Observable<const InputEvent *> *source);
protected:
int handleInputEvent(const InputEvent *event);
};
extern InputBroker *inputBroker;

View File

@@ -0,0 +1,148 @@
#include "configuration.h"
#include "RotaryEncoderInterruptBase.h"
RotaryEncoderInterruptBase::RotaryEncoderInterruptBase(
const char *name) :
concurrency::OSThread(name)
{
this->_originName = name;
}
void RotaryEncoderInterruptBase::init(
uint8_t pinA, uint8_t pinB, uint8_t pinPress,
char eventCw, char eventCcw, char eventPressed,
// std::function<void(void)> onIntA, std::function<void(void)> onIntB, std::function<void(void)> onIntPress) :
void (*onIntA)(), void (*onIntB)(), void (*onIntPress)())
{
this->_pinA = pinA;
this->_pinB = pinB;
this->_eventCw = eventCw;
this->_eventCcw = eventCcw;
this->_eventPressed = eventPressed;
pinMode(pinPress, INPUT_PULLUP);
pinMode(this->_pinA, INPUT_PULLUP);
pinMode(this->_pinB, INPUT_PULLUP);
// attachInterrupt(pinPress, onIntPress, RISING);
attachInterrupt(pinPress, onIntPress, RISING);
attachInterrupt(this->_pinA, onIntA, CHANGE);
attachInterrupt(this->_pinB, onIntB, CHANGE);
this->rotaryLevelA = digitalRead(this->_pinA);
this->rotaryLevelB = digitalRead(this->_pinB);
DEBUG_MSG("Rotary initialized (%d, %d, %d)\n",
this->_pinA, this->_pinB, pinPress);
}
int32_t RotaryEncoderInterruptBase::runOnce()
{
InputEvent e;
e.inputEvent = InputEventChar_KEY_NONE;
e.source = this->_originName;
if (this->action == ROTARY_ACTION_PRESSED)
{
DEBUG_MSG("Rotary event Press\n");
e.inputEvent = this->_eventPressed;
}
else if (this->action == ROTARY_ACTION_CW)
{
DEBUG_MSG("Rotary event CW\n");
e.inputEvent = this->_eventCw;
}
else if (this->action == ROTARY_ACTION_CCW)
{
DEBUG_MSG("Rotary event CW\n");
e.inputEvent = this->_eventCcw;
}
if (e.inputEvent != InputEventChar_KEY_NONE)
{
this->notifyObservers(&e);
}
this->action = ROTARY_ACTION_NONE;
return 30000; // TODO: technically this can be MAX_INT
}
void RotaryEncoderInterruptBase::intPressHandler()
{
this->action = ROTARY_ACTION_PRESSED;
setIntervalFromNow(20); // TODO: this modifies a non-volatile variable!
}
void RotaryEncoderInterruptBase::intAHandler()
{
// CW rotation (at least on most common rotary encoders)
int currentLevelA = digitalRead(this->_pinA);
if (this->rotaryLevelA == currentLevelA)
{
return;
}
this->rotaryLevelA = currentLevelA;
intHandler(
currentLevelA == HIGH,
this->rotaryLevelB,
ROTARY_ACTION_CCW,
this->rotaryStateCCW);
}
void RotaryEncoderInterruptBase::intBHandler()
{
// CW rotation (at least on most common rotary encoders)
int currentLevelB = digitalRead(this->_pinB);
if (this->rotaryLevelB == currentLevelB)
{
return;
}
this->rotaryLevelB = currentLevelB;
this->rotaryStateCW = intHandler(
currentLevelB == HIGH,
this->rotaryLevelA,
ROTARY_ACTION_CW,
this->rotaryStateCW);
}
/**
* @brief Rotary action implementation.
* We assume, the following pin setup:
* A --||
* GND --||]========
* B --||
*
* @return The new state for rotary pin.
*/
RotaryEncoderInterruptBaseStateType RotaryEncoderInterruptBase::intHandler(
bool actualPinRaising,
int otherPinLevel,
RotaryEncoderInterruptBaseActionType action,
RotaryEncoderInterruptBaseStateType state)
{
RotaryEncoderInterruptBaseStateType newState =
state;
if (actualPinRaising && (otherPinLevel == LOW))
{
if (state == ROTARY_EVENT_CLEARED)
{
newState = ROTARY_EVENT_OCCURRED;
if ((this->action != ROTARY_ACTION_PRESSED)
&& (this->action != action))
{
this->action = action;
DEBUG_MSG("Rotary action\n");
}
}
}
else if (!actualPinRaising && (otherPinLevel == HIGH))
{
// Logic to prevent bouncing.
newState = ROTARY_EVENT_CLEARED;
}
setIntervalFromNow(50); // TODO: this modifies a non-volatile variable!
return newState;
}

View File

@@ -0,0 +1,57 @@
#pragma once
#include "SinglePortPlugin.h" // TODO: what header file to include?
#include "InputBroker.h"
enum RotaryEncoderInterruptBaseStateType
{
ROTARY_EVENT_OCCURRED,
ROTARY_EVENT_CLEARED
};
enum RotaryEncoderInterruptBaseActionType
{
ROTARY_ACTION_NONE,
ROTARY_ACTION_PRESSED,
ROTARY_ACTION_CW,
ROTARY_ACTION_CCW
};
class RotaryEncoderInterruptBase :
public Observable<const InputEvent *>,
private concurrency::OSThread
{
public:
explicit RotaryEncoderInterruptBase(
const char *name);
void init(
uint8_t pinA, uint8_t pinB, uint8_t pinPress,
char eventCw, char eventCcw, char eventPressed,
// std::function<void(void)> onIntA, std::function<void(void)> onIntB, std::function<void(void)> onIntPress);
void (*onIntA)(), void (*onIntB)(), void (*onIntPress)());
void intPressHandler();
void intAHandler();
void intBHandler();
protected:
virtual int32_t runOnce() override;
RotaryEncoderInterruptBaseStateType intHandler(
bool actualPinRaising,
int otherPinLevel,
RotaryEncoderInterruptBaseActionType action,
RotaryEncoderInterruptBaseStateType state);
volatile RotaryEncoderInterruptBaseStateType rotaryStateCW = ROTARY_EVENT_CLEARED;
volatile RotaryEncoderInterruptBaseStateType rotaryStateCCW = ROTARY_EVENT_CLEARED;
volatile int rotaryLevelA = LOW;
volatile int rotaryLevelB = LOW;
volatile RotaryEncoderInterruptBaseActionType action = ROTARY_ACTION_NONE;
private:
uint8_t _pinA = 0;
uint8_t _pinB = 0;
char _eventCw = InputEventChar_KEY_NONE;
char _eventCcw = InputEventChar_KEY_NONE;
char _eventPressed = InputEventChar_KEY_NONE;
const char *_originName;
};

View File

@@ -0,0 +1,51 @@
#include "RotaryEncoderInterruptImpl1.h"
#include "InputBroker.h"
RotaryEncoderInterruptImpl1 *rotaryEncoderInterruptImpl1;
RotaryEncoderInterruptImpl1::RotaryEncoderInterruptImpl1() :
RotaryEncoderInterruptBase(
"rotEnc1")
{
}
void RotaryEncoderInterruptImpl1::init()
{
if (!radioConfig.preferences.rotary1_enabled)
{
// Input device is disabled.
return;
}
uint8_t pinA = radioConfig.preferences.rotary1_pin_a;
uint8_t pinB = radioConfig.preferences.rotary1_pin_b;
uint8_t pinPress = radioConfig.preferences.rotary1_pin_press;
char eventCw =
static_cast<char>(radioConfig.preferences.rotary1_event_cw);
char eventCcw =
static_cast<char>(radioConfig.preferences.rotary1_event_ccw);
char eventPressed =
static_cast<char>(radioConfig.preferences.rotary1_event_press);
//radioConfig.preferences.ext_notification_plugin_output
RotaryEncoderInterruptBase::init(
pinA, pinB, pinPress,
eventCw, eventCcw, eventPressed,
RotaryEncoderInterruptImpl1::handleIntA,
RotaryEncoderInterruptImpl1::handleIntB,
RotaryEncoderInterruptImpl1::handleIntPressed);
inputBroker->registerSource(this);
}
void RotaryEncoderInterruptImpl1::handleIntA()
{
rotaryEncoderInterruptImpl1->intAHandler();
}
void RotaryEncoderInterruptImpl1::handleIntB()
{
rotaryEncoderInterruptImpl1->intBHandler();
}
void RotaryEncoderInterruptImpl1::handleIntPressed()
{
rotaryEncoderInterruptImpl1->intPressHandler();
}

View File

@@ -0,0 +1,22 @@
#pragma once
#include "RotaryEncoderInterruptBase.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 RotaryEncoderInterruptImpl1 :
public RotaryEncoderInterruptBase
{
public:
RotaryEncoderInterruptImpl1();
void init();
static void handleIntA();
static void handleIntB();
static void handleIntPressed();
};
extern RotaryEncoderInterruptImpl1 *rotaryEncoderInterruptImpl1;

View File

@@ -42,9 +42,6 @@
#include "SX1268Interface.h" #include "SX1268Interface.h"
#include "LLCC68Interface.h" #include "LLCC68Interface.h"
#ifdef NRF52_SERIES
#include "variant.h"
#endif
using namespace concurrency; using namespace concurrency;
@@ -144,7 +141,7 @@ class PowerFSMThread : public OSThread
PowerFSMThread() : OSThread("PowerFSM") {} PowerFSMThread() : OSThread("PowerFSM") {}
protected: protected:
int32_t runOnce() int32_t runOnce() override
{ {
powerFSM.run_machine(); powerFSM.run_machine();
@@ -245,7 +242,7 @@ class ButtonThread : public OSThread
protected: protected:
/// If the button is pressed we suppress CPU sleep until release /// If the button is pressed we suppress CPU sleep until release
int32_t runOnce() int32_t runOnce() override
{ {
canSleep = true; // Assume we should not keep the board awake canSleep = true; // Assume we should not keep the board awake
@@ -303,8 +300,9 @@ class ButtonThread : public OSThread
static void userButtonPressedLong() static void userButtonPressedLong()
{ {
// DEBUG_MSG("Long press!\n"); // DEBUG_MSG("Long press!\n");
#ifndef NRF52_SERIES
screen->adjustBrightness(); screen->adjustBrightness();
#endif
// If user button is held down for 5 seconds, shutdown the device. // If user button is held down for 5 seconds, shutdown the device.
if (millis() - longPressTime > 5 * 1000) { if (millis() - longPressTime > 5 * 1000) {
#ifdef TBEAM_V10 #ifdef TBEAM_V10
@@ -316,6 +314,7 @@ class ButtonThread : public OSThread
// Do actual shutdown when button released, otherwise the button release // Do actual shutdown when button released, otherwise the button release
// may wake the board immediatedly. // may wake the board immediatedly.
if (!shutdown_on_long_stop) { if (!shutdown_on_long_stop) {
screen->startShutdownScreen();
DEBUG_MSG("Shutdown from long press"); DEBUG_MSG("Shutdown from long press");
playBeep(); playBeep();
ledOff(PIN_LED1); ledOff(PIN_LED1);
@@ -357,6 +356,7 @@ class ButtonThread : public OSThread
longPressTime = 0; longPressTime = 0;
if (shutdown_on_long_stop) { if (shutdown_on_long_stop) {
playShutdownMelody(); playShutdownMelody();
delay(3000);
power->shutdown(); power->shutdown();
} }
} }
@@ -699,8 +699,9 @@ axpDebugOutput.setup();
#endif #endif
uint32_t rebootAtMsec; // If not zero we will reboot at this time (used to reboot shortly after the update completes) uint32_t rebootAtMsec; // If not zero we will reboot at this time (used to reboot shortly after the update completes)
uint32_t shutdownAtMsec; // If not zero we will shutdown at this time (used to shutdown from python or mobile client)
void rebootCheck() void powerCommandsCheck()
{ {
if (rebootAtMsec && millis() > rebootAtMsec) { if (rebootAtMsec && millis() > rebootAtMsec) {
#ifndef NO_ESP32 #ifndef NO_ESP32
@@ -710,6 +711,30 @@ void rebootCheck()
DEBUG_MSG("FIXME implement reboot for this platform"); DEBUG_MSG("FIXME implement reboot for this platform");
#endif #endif
} }
#if NRF52_SERIES
if (shutdownAtMsec) {
screen->startShutdownScreen();
playBeep();
ledOff(PIN_LED1);
ledOff(PIN_LED2);
}
#endif
if (shutdownAtMsec && millis() > shutdownAtMsec) {
DEBUG_MSG("Shutting down from admin command\n");
#ifdef TBEAM_V10
if (axp192_found == true) {
setLed(false);
power->shutdown();
}
#elif NRF52_SERIES
playShutdownMelody();
power->shutdown();
#else
DEBUG_MSG("FIXME implement shutdown for this platform");
#endif
}
} }
// If a thread does something that might need for it to be rescheduled ASAP it can set this flag // If a thread does something that might need for it to be rescheduled ASAP it can set this flag
@@ -730,7 +755,7 @@ void loop()
#ifdef NRF52_SERIES #ifdef NRF52_SERIES
nrf52Loop(); nrf52Loop();
#endif #endif
rebootCheck(); powerCommandsCheck();
// For debugging // For debugging
// if (rIf) ((RadioLibInterface *)rIf)->isActivelyReceiving(); // if (rIf) ((RadioLibInterface *)rIf)->isActivelyReceiving();

View File

@@ -21,6 +21,7 @@ extern graphics::Screen *screen;
const char *getDeviceName(); const char *getDeviceName();
extern uint32_t rebootAtMsec; extern uint32_t rebootAtMsec;
extern uint32_t shutdownAtMsec;
// If a thread does something that might need for it to be rescheduled ASAP it can set this flag // If a thread does something that might need for it to be rescheduled ASAP it can set this flag
// This will supress the current delay and instead try to run ASAP. // This will supress the current delay and instead try to run ASAP.

View File

@@ -247,7 +247,7 @@ static int mem_test(uint32_t *_start, size_t len, bool doRead = true, bool doWri
{ {
volatile uint32_t *addr; volatile uint32_t *addr;
volatile uint32_t *start = (volatile uint32_t *)_start; volatile uint32_t *start = (volatile uint32_t *)_start;
volatile uint32_t *end = start + len / sizeof(uint32_t); const volatile uint32_t *end = start + len / sizeof(uint32_t);
uint32_t pattern = 0; uint32_t pattern = 0;
uint32_t val; uint32_t val;
uint32_t readback; uint32_t readback;
@@ -315,4 +315,4 @@ void doMemTest()
assert(0); // FIXME report error better assert(0); // FIXME report error better
iter++; iter++;
} }

View File

@@ -102,7 +102,7 @@ void Channels::initDefaultChannel(ChannelIndex chIndex)
CryptoKey Channels::getKey(ChannelIndex chIndex) CryptoKey Channels::getKey(ChannelIndex chIndex)
{ {
Channel &ch = getByIndex(chIndex); Channel &ch = getByIndex(chIndex);
ChannelSettings &channelSettings = ch.settings; const ChannelSettings &channelSettings = ch.settings;
assert(ch.has_settings); assert(ch.has_settings);
CryptoKey k; CryptoKey k;
@@ -206,7 +206,7 @@ void Channels::setChannel(const Channel &c)
const char *Channels::getName(size_t chIndex) const char *Channels::getName(size_t chIndex)
{ {
// Convert the short "" representation for Default into a usable string // Convert the short "" representation for Default into a usable string
ChannelSettings &channelSettings = getByIndex(chIndex).settings; const ChannelSettings &channelSettings = getByIndex(chIndex).settings;
const char *channelName = channelSettings.name; const char *channelName = channelSettings.name;
if (!*channelName) { // emptystring if (!*channelName) { // emptystring
// Per mesh.proto spec, if bandwidth is specified we must ignore modemConfig enum, we assume that in that case // Per mesh.proto spec, if bandwidth is specified we must ignore modemConfig enum, we assume that in that case

View File

@@ -26,9 +26,12 @@ class Channels
ChannelIndex activeChannelIndex = 0; ChannelIndex activeChannelIndex = 0;
/// the precomputed hashes for each of our channels, or -1 for invalid /// the precomputed hashes for each of our channels, or -1 for invalid
int16_t hashes[MAX_NUM_CHANNELS]; int16_t hashes[MAX_NUM_CHANNELS] = {};
public: public:
Channels() {}
/// Well known channel names /// Well known channel names
static const char *adminChannel, *gpioChannel, *serialChannel; static const char *adminChannel, *gpioChannel, *serialChannel;
@@ -134,4 +137,4 @@ class Channels
}; };
/// Singleton channel table /// Singleton channel table
extern Channels channels; extern Channels channels;

View File

@@ -20,9 +20,9 @@ class CryptoEngine
{ {
protected: protected:
/** Our per packet nonce */ /** Our per packet nonce */
uint8_t nonce[16]; uint8_t nonce[16] = {0};
CryptoKey key; CryptoKey key = {};
public: public:
virtual ~CryptoEngine() {} virtual ~CryptoEngine() {}

View File

@@ -8,14 +8,14 @@ class DSRRouter : public ReliableRouter
* Every (non duplicate) packet this node receives will be passed through this method. This allows subclasses to * Every (non duplicate) packet this node receives will be passed through this method. This allows subclasses to
* update routing tables etc... based on what we overhear (even for messages not destined to our node) * update routing tables etc... based on what we overhear (even for messages not destined to our node)
*/ */
virtual void sniffReceived(const MeshPacket *p, const Routing *c); virtual void sniffReceived(const MeshPacket *p, const Routing *c) override;
/** /**
* Send a packet on a suitable interface. This routine will * Send a packet on a suitable interface. This routine will
* later free() the packet to pool. This routine is not allowed to stall. * later free() the packet to pool. This routine is not allowed to stall.
* If the txmit queue is full it might return an error * If the txmit queue is full it might return an error
*/ */
virtual ErrorCode send(MeshPacket *p); virtual ErrorCode send(MeshPacket *p) override;
private: private:
/** /**
@@ -77,4 +77,4 @@ class DSRRouter : public ReliableRouter
* when the discovery is complete. * when the discovery is complete.
*/ */
void startDiscovery(NodeNum dest); void startDiscovery(NodeNum dest);
}; };

View File

@@ -41,7 +41,7 @@ class FloodingRouter : public Router, protected PacketHistory
* later free() the packet to pool. This routine is not allowed to stall. * later free() the packet to pool. This routine is not allowed to stall.
* If the txmit queue is full it might return an error * If the txmit queue is full it might return an error
*/ */
virtual ErrorCode send(MeshPacket *p); virtual ErrorCode send(MeshPacket *p) override;
protected: protected:
/** /**
@@ -50,10 +50,10 @@ class FloodingRouter : public Router, protected PacketHistory
* Called immedately on receiption, before any further processing. * Called immedately on receiption, before any further processing.
* @return true to abandon the packet * @return true to abandon the packet
*/ */
virtual bool shouldFilterReceived(MeshPacket *p); virtual bool shouldFilterReceived(MeshPacket *p) override;
/** /**
* Look for broadcasts we need to rebroadcast * Look for broadcasts we need to rebroadcast
*/ */
virtual void sniffReceived(const MeshPacket *p, const Routing *c); virtual void sniffReceived(const MeshPacket *p, const Routing *c) override;
}; };

View File

@@ -58,7 +58,7 @@ template <class T> class MemoryDynamic : public Allocator<T>
{ {
public: public:
/// Return a buffer for use by others /// Return a buffer for use by others
virtual void release(T *p) virtual void release(T *p) override
{ {
assert(p); assert(p);
free(p); free(p);
@@ -66,7 +66,7 @@ template <class T> class MemoryDynamic : public Allocator<T>
protected: protected:
// Alloc some storage // Alloc some storage
virtual T *alloc(TickType_t maxWait) virtual T *alloc(TickType_t maxWait) override
{ {
T *p = (T *)malloc(sizeof(T)); T *p = (T *)malloc(sizeof(T));
assert(p); assert(p);
@@ -87,7 +87,7 @@ template <class T> class MemoryPool : public Allocator<T>
size_t maxElements; size_t maxElements;
public: public:
MemoryPool(size_t _maxElements) : dead(_maxElements), maxElements(_maxElements) explicit MemoryPool(size_t _maxElements) : dead(_maxElements), maxElements(_maxElements)
{ {
buf = new T[maxElements]; buf = new T[maxElements];
@@ -99,7 +99,7 @@ template <class T> class MemoryPool : public Allocator<T>
~MemoryPool() { delete[] buf; } ~MemoryPool() { delete[] buf; }
/// Return a buffer for use by others /// Return a buffer for use by others
virtual void release(T *p) void release(T *p)
{ {
assert(p >= buf && assert(p >= buf &&
(size_t)(p - buf) < (size_t)(p - buf) <

View File

@@ -18,7 +18,7 @@ class MeshPacketQueue
bool replaceLowerPriorityPacket(MeshPacket *mp); bool replaceLowerPriorityPacket(MeshPacket *mp);
public: public:
MeshPacketQueue(size_t _maxLen); explicit MeshPacketQueue(size_t _maxLen);
/** enqueue a packet, return false if full */ /** enqueue a packet, return false if full */
bool enqueue(MeshPacket *p); bool enqueue(MeshPacket *p);
@@ -30,4 +30,4 @@ class MeshPacketQueue
/** Attempt to find and remove a packet from this queue. Returns the packet which was removed from the queue */ /** Attempt to find and remove a packet from this queue. Returns the packet which was removed from the queue */
MeshPacket *remove(NodeNum from, PacketId id); MeshPacket *remove(NodeNum from, PacketId id);
}; };

View File

@@ -235,3 +235,18 @@ std::vector<MeshPlugin *> MeshPlugin::GetMeshPluginsWithUIFrames()
} }
return pluginsWithUIFrames; return pluginsWithUIFrames;
} }
void MeshPlugin::observeUIEvents(
Observer<const UIFrameEvent *> *observer)
{
std::vector<MeshPlugin *> pluginsWithUIFrames;
for (auto i = plugins->begin(); i != plugins->end(); ++i) {
auto &pi = **i;
Observable<const UIFrameEvent *> *observable =
pi.getUIFrameObservable();
if (observable != NULL) {
DEBUG_MSG("Plugin wants a UI Frame\n");
observer->observe(observable);
}
}
}

View File

@@ -21,6 +21,14 @@ enum class ProcessMessage
STOP = 1, STOP = 1,
}; };
/*
* This struct is used by Screen to figure out whether screen frame should be updated.
*/
typedef struct _UIFrameEvent {
bool frameChanged;
bool needRedraw;
} UIFrameEvent;
/** A baseclass for any mesh "plugin". /** A baseclass for any mesh "plugin".
* *
* A plugin allows you to add new features to meshtastic device code, without needing to know messaging details. * A plugin allows you to add new features to meshtastic device code, without needing to know messaging details.
@@ -48,6 +56,7 @@ class MeshPlugin
static void callPlugins(const MeshPacket &mp, RxSource src = RX_SRC_RADIO); static void callPlugins(const MeshPacket &mp, RxSource src = RX_SRC_RADIO);
static std::vector<MeshPlugin *> GetMeshPluginsWithUIFrames(); static std::vector<MeshPlugin *> GetMeshPluginsWithUIFrames();
static void observeUIEvents(Observer<const UIFrameEvent *> *observer);
#ifndef NO_SCREEN #ifndef NO_SCREEN
virtual void drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) { return; } virtual void drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) { return; }
#endif #endif
@@ -119,6 +128,7 @@ class MeshPlugin
* @return true if you want to be alloced a UI screen frame * @return true if you want to be alloced a UI screen frame
*/ */
virtual bool wantUIFrame() { return false; } virtual bool wantUIFrame() { return false; }
virtual Observable<const UIFrameEvent *>* getUIFrameObservable() { return NULL; }
MeshPacket *allocAckNak(Routing_Error err, NodeNum to, PacketId idFrom, ChannelIndex chIndex); MeshPacket *allocAckNak(Routing_Error err, NodeNum to, PacketId idFrom, ChannelIndex chIndex);
@@ -144,4 +154,4 @@ class MeshPlugin
/** set the destination and packet parameters of packet p intended as a reply to a particular "to" packet /** set the destination and packet parameters of packet p intended as a reply to a particular "to" packet
* This ensures that if the request packet was sent reliably, the reply is sent that way as well. * This ensures that if the request packet was sent reliably, the reply is sent that way as well.
*/ */
void setReplyTo(MeshPacket *p, const MeshPacket &to); void setReplyTo(MeshPacket *p, const MeshPacket &to);

View File

@@ -407,8 +407,8 @@ void NodeDB::saveToDisk()
#ifdef FS #ifdef FS
FS.mkdir("/prefs"); FS.mkdir("/prefs");
#endif #endif
bool okay = saveProto(preffile, DeviceState_size, sizeof(devicestate), DeviceState_fields, &devicestate); saveProto(preffile, DeviceState_size, sizeof(devicestate), DeviceState_fields, &devicestate);
okay &= saveProto(radiofile, RadioConfig_size, sizeof(RadioConfig), RadioConfig_fields, &radioConfig); saveProto(radiofile, RadioConfig_size, sizeof(RadioConfig), RadioConfig_fields, &radioConfig);
saveChannelsToDisk(); saveChannelsToDisk();
// remove any pre 1.2 pref files, turn on after 1.2 is in beta // remove any pre 1.2 pref files, turn on after 1.2 is in beta

View File

@@ -45,7 +45,7 @@ class PhoneAPI
/// We temporarily keep the nodeInfo here between the call to available and getFromRadio /// We temporarily keep the nodeInfo here between the call to available and getFromRadio
const NodeInfo *nodeInfoForPhone = NULL; const NodeInfo *nodeInfoForPhone = NULL;
ToRadio toRadioScratch; // this is a static scratch object, any data must be copied elsewhere before returning ToRadio toRadioScratch = {0}; // this is a static scratch object, any data must be copied elsewhere before returning
/// Use to ensure that clients don't get confused about old messages from the radio /// Use to ensure that clients don't get confused about old messages from the radio
uint32_t config_nonce = 0; uint32_t config_nonce = 0;
@@ -58,7 +58,7 @@ class PhoneAPI
// Call this when the client drops the connection, resets the state to STATE_SEND_NOTHING // 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. // Unregisters our observer. A closed connection **can** be reopened by calling init again.
virtual void close(); void close();
/** /**
* Handle a ToRadio protobuf * Handle a ToRadio protobuf
@@ -86,7 +86,7 @@ class PhoneAPI
protected: protected:
/// Our fromradio packet while it is being assembled /// Our fromradio packet while it is being assembled
FromRadio fromRadioScratch; FromRadio fromRadioScratch = {};
/** the last msec we heard from the client on the other side of this link */ /** the last msec we heard from the client on the other side of this link */
uint32_t lastContactMsec = 0; uint32_t lastContactMsec = 0;
@@ -123,5 +123,5 @@ class PhoneAPI
bool handleToRadioPacket(MeshPacket &p); bool handleToRadioPacket(MeshPacket &p);
/// If the mesh service tells us fromNum has changed, tell the phone /// If the mesh service tells us fromNum has changed, tell the phone
virtual int onNotify(uint32_t newValue); virtual int onNotify(uint32_t newValue) override;
}; };

View File

@@ -8,7 +8,7 @@
template <class T> class PointerQueue : public TypedQueue<T *> template <class T> class PointerQueue : public TypedQueue<T *>
{ {
public: public:
PointerQueue(int maxElements) : TypedQueue<T *>(maxElements) {} explicit PointerQueue(int maxElements) : TypedQueue<T *>(maxElements) {}
// returns a ptr or null if the queue was empty // returns a ptr or null if the queue was empty
T *dequeuePtr(TickType_t maxWait = portMAX_DELAY) T *dequeuePtr(TickType_t maxWait = portMAX_DELAY)

View File

@@ -51,7 +51,7 @@ template <class T> class ProtobufPlugin : protected SinglePortPlugin
@return ProcessMessage::STOP if you've guaranteed you've handled this message and no other handlers should be considered for it @return ProcessMessage::STOP if you've guaranteed you've handled this message and no other handlers should be considered for it
*/ */
virtual ProcessMessage handleReceived(const MeshPacket &mp) virtual ProcessMessage handleReceived(const MeshPacket &mp) override
{ {
// FIXME - we currently update position data in the DB only if the message was a broadcast or destined to us // FIXME - we currently update position data in the DB only if the message was a broadcast or destined to us
// it would be better to update even if the message was destined to others. // it would be better to update even if the message was destined to others.

View File

@@ -9,31 +9,31 @@
*/ */
class RF95Interface : public RadioLibInterface class RF95Interface : public RadioLibInterface
{ {
RadioLibRF95 *lora; // Either a RFM95 or RFM96 depending on what was stuffed on this board RadioLibRF95 *lora = NULL; // Either a RFM95 or RFM96 depending on what was stuffed on this board
public: public:
RF95Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, SPIClass &spi); RF95Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, SPIClass &spi);
bool isIRQPending() { return lora->getPendingIRQ(); } bool isIRQPending() override { return lora->getPendingIRQ(); }
/// Initialise the Driver transport hardware and software. /// Initialise the Driver transport hardware and software.
/// Make sure the Driver is properly configured before calling init(). /// Make sure the Driver is properly configured before calling init().
/// \return true if initialisation succeeded. /// \return true if initialisation succeeded.
virtual bool init(); virtual bool init() override;
/// Apply any radio provisioning changes /// Apply any radio provisioning changes
/// Make sure the Driver is properly configured before calling init(). /// Make sure the Driver is properly configured before calling init().
/// \return true if initialisation succeeded. /// \return true if initialisation succeeded.
virtual bool reconfigure(); virtual bool reconfigure() override;
/// Prepare hardware for sleep. Call this _only_ for deep sleep, not needed for light sleep. /// Prepare hardware for sleep. Call this _only_ for deep sleep, not needed for light sleep.
virtual bool sleep(); virtual bool sleep() override;
protected: protected:
/** /**
* Glue functions called from ISR land * Glue functions called from ISR land
*/ */
virtual void disableInterrupt(); virtual void disableInterrupt() override;
/** /**
* Enable a particular ISR callback glue function * Enable a particular ISR callback glue function
@@ -41,26 +41,26 @@ class RF95Interface : public RadioLibInterface
virtual void enableInterrupt(void (*callback)()) { lora->setDio0Action(callback); } virtual void enableInterrupt(void (*callback)()) { lora->setDio0Action(callback); }
/** are we actively receiving a packet (only called during receiving state) */ /** are we actively receiving a packet (only called during receiving state) */
virtual bool isActivelyReceiving(); virtual bool isActivelyReceiving() override;
/** /**
* Start waiting to receive a message * Start waiting to receive a message
*/ */
virtual void startReceive(); virtual void startReceive() override;
/** /**
* Add SNR data to received messages * Add SNR data to received messages
*/ */
virtual void addReceiveMetadata(MeshPacket *mp); virtual void addReceiveMetadata(MeshPacket *mp) override;
virtual void setStandby(); virtual void setStandby() override;
/** /**
* We override to turn on transmitter power as needed. * We override to turn on transmitter power as needed.
*/ */
virtual void configHardwareForSend(); virtual void configHardwareForSend() override;
private: private:
/** Some boards require GPIO control of tx vs rx paths */ /** Some boards require GPIO control of tx vs rx paths */
void setTransmitEnable(bool txon); void setTransmitEnable(bool txon);
}; };

View File

@@ -205,8 +205,8 @@ class RadioInterface
class SimRadio : public RadioInterface class SimRadio : public RadioInterface
{ {
public: public:
virtual ErrorCode send(MeshPacket *p); virtual ErrorCode send(MeshPacket *p) override;
}; };
/// Debug printing for packets /// Debug printing for packets
void printPacket(const char *prefix, const MeshPacket *p); void printPacket(const char *prefix, const MeshPacket *p);

View File

@@ -4,10 +4,6 @@
#include "RadioInterface.h" #include "RadioInterface.h"
#include "MeshPacketQueue.h" #include "MeshPacketQueue.h"
#ifdef CubeCell_BoardPlus
#define RADIOLIB_SOFTWARE_SERIAL_UNSUPPORTED
#endif
#define RADIOLIB_EXCLUDE_HTTP #define RADIOLIB_EXCLUDE_HTTP
#include <RadioLib.h> #include <RadioLib.h>
@@ -58,7 +54,7 @@ class LockingModule : public Module
\param numBytes Number of bytes to transfer. \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); virtual void SPItransfer(uint8_t cmd, uint8_t reg, uint8_t *dataOut, uint8_t *dataIn, uint8_t numBytes) override;
}; };
class RadioLibInterface : public RadioInterface, protected concurrency::NotifiedWorkerThread class RadioLibInterface : public RadioInterface, protected concurrency::NotifiedWorkerThread
@@ -99,7 +95,7 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified
PhysicalLayer *iface; PhysicalLayer *iface;
/// are _trying_ to receive a packet currently (note - we might just be waiting for one) /// are _trying_ to receive a packet currently (note - we might just be waiting for one)
bool isReceiving; bool isReceiving = false;
public: public:
/** Our ISR code currently needs this to find our active instance /** Our ISR code currently needs this to find our active instance
@@ -120,14 +116,14 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified
RadioLibInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, SPIClass &spi, RadioLibInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, SPIClass &spi,
PhysicalLayer *iface = NULL); PhysicalLayer *iface = NULL);
virtual ErrorCode send(MeshPacket *p); virtual ErrorCode send(MeshPacket *p) override;
/** /**
* Return true if we think the board can go to sleep (i.e. our tx queue is empty, we are not sending or receiving) * Return true if we think the board can go to sleep (i.e. our tx queue is empty, we are not sending or receiving)
* *
* This method must be used before putting the CPU into deep or light sleep. * This method must be used before putting the CPU into deep or light sleep.
*/ */
virtual bool canSleep(); virtual bool canSleep() override;
/** /**
* Start waiting to receive a message * Start waiting to receive a message
@@ -142,7 +138,7 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified
virtual bool isActivelyReceiving() = 0; virtual bool isActivelyReceiving() = 0;
/** Attempt to cancel a previously sent packet. Returns true if a packet was found we could cancel */ /** Attempt to cancel a previously sent packet. Returns true if a packet was found we could cancel */
virtual bool cancelSending(NodeNum from, PacketId id); virtual bool cancelSending(NodeNum from, PacketId id) override;
private: private:
/** if we have something waiting to send, start a short random timer so we can come check for collision before actually doing /** if we have something waiting to send, start a short random timer so we can come check for collision before actually doing
@@ -157,7 +153,7 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified
static void timerCallback(void *p1, uint32_t p2); static void timerCallback(void *p1, uint32_t p2);
virtual void onNotify(uint32_t notification); virtual void onNotify(uint32_t notification) override;
/** start an immediate transmit /** start an immediate transmit
* This method is virtual so subclasses can hook as needed, subclasses should not call directly * This method is virtual so subclasses can hook as needed, subclasses should not call directly
@@ -187,4 +183,4 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified
virtual void addReceiveMetadata(MeshPacket *mp) = 0; virtual void addReceiveMetadata(MeshPacket *mp) = 0;
virtual void setStandby() = 0; virtual void setStandby() = 0;
}; };

View File

@@ -16,7 +16,7 @@ class RadioLibRF95: public SX1278 {
\param mod Instance of Module that will be used to communicate with the %LoRa chip. \param mod Instance of Module that will be used to communicate with the %LoRa chip.
*/ */
RadioLibRF95(Module* mod); explicit RadioLibRF95(Module* mod);
// basic methods // basic methods

View File

@@ -13,7 +13,7 @@ struct GlobalPacketId {
bool operator==(const GlobalPacketId &p) const { return node == p.node && id == p.id; } bool operator==(const GlobalPacketId &p) const { return node == p.node && id == p.id; }
GlobalPacketId(const MeshPacket *p) explicit GlobalPacketId(const MeshPacket *p)
{ {
node = getFrom(p); node = getFrom(p);
id = p->id; id = p->id;
@@ -33,10 +33,10 @@ struct PendingPacket {
MeshPacket *packet; MeshPacket *packet;
/** The next time we should try to retransmit this packet */ /** The next time we should try to retransmit this packet */
uint32_t nextTxMsec; uint32_t nextTxMsec = 0;
/** Starts at NUM_RETRANSMISSIONS -1(normally 3) and counts down. Once zero it will be removed from the list */ /** Starts at NUM_RETRANSMISSIONS -1(normally 3) and counts down. Once zero it will be removed from the list */
uint8_t numRetransmissions; uint8_t numRetransmissions = 0;
/** True if we have started trying to find a route - for DSR usage /** True if we have started trying to find a route - for DSR usage
* While trying to find a route we don't actually send the data packet. We just leave it here pending until * While trying to find a route we don't actually send the data packet. We just leave it here pending until
@@ -45,7 +45,7 @@ struct PendingPacket {
bool wantRoute = false; bool wantRoute = false;
PendingPacket() {} PendingPacket() {}
PendingPacket(MeshPacket *p); explicit PendingPacket(MeshPacket *p);
}; };
class GlobalPacketIdHashFunction class GlobalPacketIdHashFunction
@@ -74,10 +74,10 @@ class ReliableRouter : public FloodingRouter
* later free() the packet to pool. This routine is not allowed to stall. * later free() the packet to pool. This routine is not allowed to stall.
* If the txmit queue is full it might return an error * If the txmit queue is full it might return an error
*/ */
virtual ErrorCode send(MeshPacket *p); virtual ErrorCode send(MeshPacket *p) override;
/** Do our retransmission handling */ /** Do our retransmission handling */
virtual int32_t runOnce() virtual int32_t runOnce() override
{ {
// Note: We must doRetransmissions FIRST, because it might queue up work for the base class runOnce implementation // Note: We must doRetransmissions FIRST, because it might queue up work for the base class runOnce implementation
auto d = doRetransmissions(); auto d = doRetransmissions();
@@ -91,7 +91,7 @@ class ReliableRouter : public FloodingRouter
/** /**
* Look for acks/naks or someone retransmitting us * Look for acks/naks or someone retransmitting us
*/ */
virtual void sniffReceived(const MeshPacket *p, const Routing *c); virtual void sniffReceived(const MeshPacket *p, const Routing *c) override;
/** /**
* Try to find the pending packet record for this ID (or NULL if not found) * Try to find the pending packet record for this ID (or NULL if not found)
@@ -102,7 +102,7 @@ class ReliableRouter : public FloodingRouter
/** /**
* We hook this method so we can see packets before FloodingRouter says they should be discarded * We hook this method so we can see packets before FloodingRouter says they should be discarded
*/ */
virtual bool shouldFilterReceived(MeshPacket *p); virtual bool shouldFilterReceived(MeshPacket *p) override;
/** /**
* Add p to the list of packets to retransmit occasionally. We will free it once we stop retransmitting. * Add p to the list of packets to retransmit occasionally. We will free it once we stop retransmitting.

View File

@@ -37,7 +37,7 @@ class Router : protected concurrency::OSThread
* do idle processing * do idle processing
* Mostly looking in our incoming rxPacket queue and calling handleReceived. * Mostly looking in our incoming rxPacket queue and calling handleReceived.
*/ */
virtual int32_t runOnce(); virtual int32_t runOnce() override;
/** /**
* Works like send, but if we are sending to the local node, we directly put the message in the receive queue. * Works like send, but if we are sending to the local node, we directly put the message in the receive queue.
@@ -143,4 +143,4 @@ extern Router *router;
/// Generate a unique packet id /// Generate a unique packet id
// FIXME, move this someplace better // FIXME, move this someplace better
PacketId generatePacketId(); PacketId generatePacketId();

View File

@@ -9,7 +9,7 @@ class SX1268Interface : public SX126xInterface<SX1268>
{ {
public: public:
/// override frequency of the SX1268 module regardless of the region (use EU433 value) /// override frequency of the SX1268 module regardless of the region (use EU433 value)
virtual float getFreq() { return 433.175f; } virtual float getFreq() override { return 433.175f; }
SX1268Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, SPIClass &spi); SX1268Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, SPIClass &spi);
}; };

View File

@@ -15,17 +15,17 @@ class SX126xInterface : public RadioLibInterface
/// Initialise the Driver transport hardware and software. /// Initialise the Driver transport hardware and software.
/// Make sure the Driver is properly configured before calling init(). /// Make sure the Driver is properly configured before calling init().
/// \return true if initialisation succeeded. /// \return true if initialisation succeeded.
virtual bool init(); virtual bool init() override;
/// Apply any radio provisioning changes /// Apply any radio provisioning changes
/// Make sure the Driver is properly configured before calling init(). /// Make sure the Driver is properly configured before calling init().
/// \return true if initialisation succeeded. /// \return true if initialisation succeeded.
virtual bool reconfigure(); virtual bool reconfigure() override;
/// Prepare hardware for sleep. Call this _only_ for deep sleep, not needed for light sleep. /// Prepare hardware for sleep. Call this _only_ for deep sleep, not needed for light sleep.
virtual bool sleep(); virtual bool sleep() override;
bool isIRQPending() { return lora.getIrqStatus() != 0; } bool isIRQPending() override { return lora.getIrqStatus() != 0; }
protected: protected:
@@ -39,7 +39,7 @@ class SX126xInterface : public RadioLibInterface
/** /**
* Glue functions called from ISR land * Glue functions called from ISR land
*/ */
virtual void disableInterrupt(); virtual void disableInterrupt() override;
/** /**
* Enable a particular ISR callback glue function * Enable a particular ISR callback glue function
@@ -47,24 +47,24 @@ class SX126xInterface : public RadioLibInterface
virtual void enableInterrupt(void (*callback)()) { lora.setDio1Action(callback); } virtual void enableInterrupt(void (*callback)()) { lora.setDio1Action(callback); }
/** are we actively receiving a packet (only called during receiving state) */ /** are we actively receiving a packet (only called during receiving state) */
virtual bool isActivelyReceiving(); virtual bool isActivelyReceiving() override;
/** /**
* Start waiting to receive a message * Start waiting to receive a message
*/ */
virtual void startReceive(); virtual void startReceive() override;
/** /**
* We override to turn on transmitter power as needed. * We override to turn on transmitter power as needed.
*/ */
virtual void configHardwareForSend(); virtual void configHardwareForSend() override;
/** /**
* Add SNR data to received messages * Add SNR data to received messages
*/ */
virtual void addReceiveMetadata(MeshPacket *mp); virtual void addReceiveMetadata(MeshPacket *mp) override;
virtual void setStandby(); virtual void setStandby() override;
private: private:
}; };

View File

@@ -21,7 +21,7 @@ class SinglePortPlugin : public MeshPlugin
/** /**
* @return true if you want to receive the specified portnum * @return true if you want to receive the specified portnum
*/ */
virtual bool wantPacket(const MeshPacket *p) { return p->decoded.portnum == ourPortNum; } virtual bool wantPacket(const MeshPacket *p) override { return p->decoded.portnum == ourPortNum; }
/** /**
* Return a mesh packet which has been preinited as a data packet with a particular port number. * Return a mesh packet which has been preinited as a data packet with a particular port number.

View File

@@ -35,7 +35,7 @@ class StreamAPI : public PhoneAPI, protected concurrency::OSThread
*/ */
Stream *stream; Stream *stream;
uint8_t rxBuf[MAX_STREAM_BUF_SIZE]; uint8_t rxBuf[MAX_STREAM_BUF_SIZE] = {0};
size_t rxPtr = 0; size_t rxPtr = 0;
/// time of last rx, used, to slow down our polling if we haven't heard from anyone /// time of last rx, used, to slow down our polling if we haven't heard from anyone
@@ -48,7 +48,7 @@ class StreamAPI : public PhoneAPI, protected concurrency::OSThread
* Currently we require frequent invocation from loop() to check for arrived serial packets and to send new packets to the * Currently we require frequent invocation from loop() to check for arrived serial packets and to send new packets to the
* phone. * phone.
*/ */
virtual int32_t runOnce(); virtual int32_t runOnce() override;
private: private:
/** /**
@@ -67,10 +67,10 @@ class StreamAPI : public PhoneAPI, protected concurrency::OSThread
*/ */
void emitRebooted(); void emitRebooted();
virtual void onConnectionChanged(bool connected); virtual void onConnectionChanged(bool connected) override;
/// Check the current underlying physical link to see if the client is currently connected /// Check the current underlying physical link to see if the client is currently connected
virtual bool checkIsConnected() = 0; virtual bool checkIsConnected() override = 0;
/** /**
* Send the current txBuffer over our stream * Send the current txBuffer over our stream
@@ -81,5 +81,5 @@ class StreamAPI : public PhoneAPI, protected concurrency::OSThread
bool canWrite = true; bool canWrite = true;
/// Subclasses can use this scratch buffer if they wish /// Subclasses can use this scratch buffer if they wish
uint8_t txBuf[MAX_STREAM_BUF_SIZE]; uint8_t txBuf[MAX_STREAM_BUF_SIZE] = {0};
}; };

View File

@@ -19,9 +19,8 @@ template <class T> class TypedQueue
concurrency::OSThread *reader = NULL; concurrency::OSThread *reader = NULL;
public: public:
TypedQueue(int maxElements) explicit TypedQueue(int maxElements) : h(xQueueCreate(maxElements, sizeof(T)))
{ {
h = xQueueCreate(maxElements, sizeof(T));
assert(h); assert(h);
} }

View File

@@ -4,6 +4,7 @@
#ifndef PB_ADMIN_PB_H_INCLUDED #ifndef PB_ADMIN_PB_H_INCLUDED
#define PB_ADMIN_PB_H_INCLUDED #define PB_ADMIN_PB_H_INCLUDED
#include <pb.h> #include <pb.h>
#include "cannedmessages.pb.h"
#include "channel.pb.h" #include "channel.pb.h"
#include "mesh.pb.h" #include "mesh.pb.h"
#include "radioconfig.pb.h" #include "radioconfig.pb.h"
@@ -29,6 +30,22 @@ typedef struct _AdminMessage {
bool confirm_set_radio; bool confirm_set_radio;
bool exit_simulator; bool exit_simulator;
int32_t reboot_seconds; int32_t reboot_seconds;
bool get_canned_message_plugin_part1_request;
CannedMessagePluginMessagePart1 get_canned_message_plugin_part1_response;
bool get_canned_message_plugin_part2_request;
CannedMessagePluginMessagePart2 get_canned_message_plugin_part2_response;
bool get_canned_message_plugin_part3_request;
CannedMessagePluginMessagePart3 get_canned_message_plugin_part3_response;
bool get_canned_message_plugin_part4_request;
CannedMessagePluginMessagePart4 get_canned_message_plugin_part4_response;
bool get_canned_message_plugin_part5_request;
CannedMessagePluginMessagePart5 get_canned_message_plugin_part5_response;
CannedMessagePluginMessagePart1 set_canned_message_plugin_part1;
CannedMessagePluginMessagePart2 set_canned_message_plugin_part2;
CannedMessagePluginMessagePart3 set_canned_message_plugin_part3;
CannedMessagePluginMessagePart4 set_canned_message_plugin_part4;
CannedMessagePluginMessagePart5 set_canned_message_plugin_part5;
int32_t shutdown_seconds;
}; };
} AdminMessage; } AdminMessage;
@@ -55,6 +72,22 @@ extern "C" {
#define AdminMessage_confirm_set_radio_tag 33 #define AdminMessage_confirm_set_radio_tag 33
#define AdminMessage_exit_simulator_tag 34 #define AdminMessage_exit_simulator_tag 34
#define AdminMessage_reboot_seconds_tag 35 #define AdminMessage_reboot_seconds_tag 35
#define AdminMessage_get_canned_message_plugin_part1_request_tag 36
#define AdminMessage_get_canned_message_plugin_part1_response_tag 37
#define AdminMessage_get_canned_message_plugin_part2_request_tag 38
#define AdminMessage_get_canned_message_plugin_part2_response_tag 39
#define AdminMessage_get_canned_message_plugin_part3_request_tag 40
#define AdminMessage_get_canned_message_plugin_part3_response_tag 41
#define AdminMessage_get_canned_message_plugin_part4_request_tag 42
#define AdminMessage_get_canned_message_plugin_part4_response_tag 43
#define AdminMessage_get_canned_message_plugin_part5_request_tag 44
#define AdminMessage_get_canned_message_plugin_part5_response_tag 45
#define AdminMessage_set_canned_message_plugin_part1_tag 46
#define AdminMessage_set_canned_message_plugin_part2_tag 47
#define AdminMessage_set_canned_message_plugin_part3_tag 48
#define AdminMessage_set_canned_message_plugin_part4_tag 49
#define AdminMessage_set_canned_message_plugin_part5_tag 50
#define AdminMessage_shutdown_seconds_tag 51
/* Struct field encoding specification for nanopb */ /* Struct field encoding specification for nanopb */
#define AdminMessage_FIELDLIST(X, a) \ #define AdminMessage_FIELDLIST(X, a) \
@@ -70,7 +103,23 @@ X(a, STATIC, ONEOF, MESSAGE, (variant,get_owner_response,get_owner_respons
X(a, STATIC, ONEOF, BOOL, (variant,confirm_set_channel,confirm_set_channel), 32) \ X(a, STATIC, ONEOF, BOOL, (variant,confirm_set_channel,confirm_set_channel), 32) \
X(a, STATIC, ONEOF, BOOL, (variant,confirm_set_radio,confirm_set_radio), 33) \ X(a, STATIC, ONEOF, BOOL, (variant,confirm_set_radio,confirm_set_radio), 33) \
X(a, STATIC, ONEOF, BOOL, (variant,exit_simulator,exit_simulator), 34) \ X(a, STATIC, ONEOF, BOOL, (variant,exit_simulator,exit_simulator), 34) \
X(a, STATIC, ONEOF, INT32, (variant,reboot_seconds,reboot_seconds), 35) X(a, STATIC, ONEOF, INT32, (variant,reboot_seconds,reboot_seconds), 35) \
X(a, STATIC, ONEOF, BOOL, (variant,get_canned_message_plugin_part1_request,get_canned_message_plugin_part1_request), 36) \
X(a, STATIC, ONEOF, MESSAGE, (variant,get_canned_message_plugin_part1_response,get_canned_message_plugin_part1_response), 37) \
X(a, STATIC, ONEOF, BOOL, (variant,get_canned_message_plugin_part2_request,get_canned_message_plugin_part2_request), 38) \
X(a, STATIC, ONEOF, MESSAGE, (variant,get_canned_message_plugin_part2_response,get_canned_message_plugin_part2_response), 39) \
X(a, STATIC, ONEOF, BOOL, (variant,get_canned_message_plugin_part3_request,get_canned_message_plugin_part3_request), 40) \
X(a, STATIC, ONEOF, MESSAGE, (variant,get_canned_message_plugin_part3_response,get_canned_message_plugin_part3_response), 41) \
X(a, STATIC, ONEOF, BOOL, (variant,get_canned_message_plugin_part4_request,get_canned_message_plugin_part4_request), 42) \
X(a, STATIC, ONEOF, MESSAGE, (variant,get_canned_message_plugin_part4_response,get_canned_message_plugin_part4_response), 43) \
X(a, STATIC, ONEOF, BOOL, (variant,get_canned_message_plugin_part5_request,get_canned_message_plugin_part5_request), 44) \
X(a, STATIC, ONEOF, MESSAGE, (variant,get_canned_message_plugin_part5_response,get_canned_message_plugin_part5_response), 45) \
X(a, STATIC, ONEOF, MESSAGE, (variant,set_canned_message_plugin_part1,set_canned_message_plugin_part1), 46) \
X(a, STATIC, ONEOF, MESSAGE, (variant,set_canned_message_plugin_part2,set_canned_message_plugin_part2), 47) \
X(a, STATIC, ONEOF, MESSAGE, (variant,set_canned_message_plugin_part3,set_canned_message_plugin_part3), 48) \
X(a, STATIC, ONEOF, MESSAGE, (variant,set_canned_message_plugin_part4,set_canned_message_plugin_part4), 49) \
X(a, STATIC, ONEOF, MESSAGE, (variant,set_canned_message_plugin_part5,set_canned_message_plugin_part5), 50) \
X(a, STATIC, ONEOF, INT32, (variant,shutdown_seconds,shutdown_seconds), 51)
#define AdminMessage_CALLBACK NULL #define AdminMessage_CALLBACK NULL
#define AdminMessage_DEFAULT NULL #define AdminMessage_DEFAULT NULL
#define AdminMessage_variant_set_radio_MSGTYPE RadioConfig #define AdminMessage_variant_set_radio_MSGTYPE RadioConfig
@@ -79,6 +128,16 @@ X(a, STATIC, ONEOF, INT32, (variant,reboot_seconds,reboot_seconds), 35)
#define AdminMessage_variant_get_radio_response_MSGTYPE RadioConfig #define AdminMessage_variant_get_radio_response_MSGTYPE RadioConfig
#define AdminMessage_variant_get_channel_response_MSGTYPE Channel #define AdminMessage_variant_get_channel_response_MSGTYPE Channel
#define AdminMessage_variant_get_owner_response_MSGTYPE User #define AdminMessage_variant_get_owner_response_MSGTYPE User
#define AdminMessage_variant_get_canned_message_plugin_part1_response_MSGTYPE CannedMessagePluginMessagePart1
#define AdminMessage_variant_get_canned_message_plugin_part2_response_MSGTYPE CannedMessagePluginMessagePart2
#define AdminMessage_variant_get_canned_message_plugin_part3_response_MSGTYPE CannedMessagePluginMessagePart3
#define AdminMessage_variant_get_canned_message_plugin_part4_response_MSGTYPE CannedMessagePluginMessagePart4
#define AdminMessage_variant_get_canned_message_plugin_part5_response_MSGTYPE CannedMessagePluginMessagePart5
#define AdminMessage_variant_set_canned_message_plugin_part1_MSGTYPE CannedMessagePluginMessagePart1
#define AdminMessage_variant_set_canned_message_plugin_part2_MSGTYPE CannedMessagePluginMessagePart2
#define AdminMessage_variant_set_canned_message_plugin_part3_MSGTYPE CannedMessagePluginMessagePart3
#define AdminMessage_variant_set_canned_message_plugin_part4_MSGTYPE CannedMessagePluginMessagePart4
#define AdminMessage_variant_set_canned_message_plugin_part5_MSGTYPE CannedMessagePluginMessagePart5
extern const pb_msgdesc_t AdminMessage_msg; extern const pb_msgdesc_t AdminMessage_msg;
@@ -86,7 +145,7 @@ extern const pb_msgdesc_t AdminMessage_msg;
#define AdminMessage_fields &AdminMessage_msg #define AdminMessage_fields &AdminMessage_msg
/* Maximum encoded size of messages (where known) */ /* Maximum encoded size of messages (where known) */
#define AdminMessage_size 535 #define AdminMessage_size 798
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */

View File

@@ -0,0 +1,24 @@
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.4.4 */
#include "cannedmessages.pb.h"
#if PB_PROTO_HEADER_VERSION != 40
#error Regenerate this file with the current version of nanopb generator.
#endif
PB_BIND(CannedMessagePluginMessagePart1, CannedMessagePluginMessagePart1, AUTO)
PB_BIND(CannedMessagePluginMessagePart2, CannedMessagePluginMessagePart2, AUTO)
PB_BIND(CannedMessagePluginMessagePart3, CannedMessagePluginMessagePart3, AUTO)
PB_BIND(CannedMessagePluginMessagePart4, CannedMessagePluginMessagePart4, AUTO)
PB_BIND(CannedMessagePluginMessagePart5, CannedMessagePluginMessagePart5, AUTO)

View File

@@ -0,0 +1,107 @@
/* Automatically generated nanopb header */
/* Generated by nanopb-0.4.4 */
#ifndef PB_CANNEDMESSAGES_PB_H_INCLUDED
#define PB_CANNEDMESSAGES_PB_H_INCLUDED
#include <pb.h>
#if PB_PROTO_HEADER_VERSION != 40
#error Regenerate this file with the current version of nanopb generator.
#endif
/* Struct definitions */
typedef struct _CannedMessagePluginMessagePart1 {
char text[200];
} CannedMessagePluginMessagePart1;
typedef struct _CannedMessagePluginMessagePart2 {
char text[200];
} CannedMessagePluginMessagePart2;
typedef struct _CannedMessagePluginMessagePart3 {
char text[200];
} CannedMessagePluginMessagePart3;
typedef struct _CannedMessagePluginMessagePart4 {
char text[200];
} CannedMessagePluginMessagePart4;
typedef struct _CannedMessagePluginMessagePart5 {
char text[200];
} CannedMessagePluginMessagePart5;
#ifdef __cplusplus
extern "C" {
#endif
/* Initializer values for message structs */
#define CannedMessagePluginMessagePart1_init_default {""}
#define CannedMessagePluginMessagePart2_init_default {""}
#define CannedMessagePluginMessagePart3_init_default {""}
#define CannedMessagePluginMessagePart4_init_default {""}
#define CannedMessagePluginMessagePart5_init_default {""}
#define CannedMessagePluginMessagePart1_init_zero {""}
#define CannedMessagePluginMessagePart2_init_zero {""}
#define CannedMessagePluginMessagePart3_init_zero {""}
#define CannedMessagePluginMessagePart4_init_zero {""}
#define CannedMessagePluginMessagePart5_init_zero {""}
/* Field tags (for use in manual encoding/decoding) */
#define CannedMessagePluginMessagePart1_text_tag 1
#define CannedMessagePluginMessagePart2_text_tag 1
#define CannedMessagePluginMessagePart3_text_tag 1
#define CannedMessagePluginMessagePart4_text_tag 1
#define CannedMessagePluginMessagePart5_text_tag 1
/* Struct field encoding specification for nanopb */
#define CannedMessagePluginMessagePart1_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, STRING, text, 1)
#define CannedMessagePluginMessagePart1_CALLBACK NULL
#define CannedMessagePluginMessagePart1_DEFAULT NULL
#define CannedMessagePluginMessagePart2_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, STRING, text, 1)
#define CannedMessagePluginMessagePart2_CALLBACK NULL
#define CannedMessagePluginMessagePart2_DEFAULT NULL
#define CannedMessagePluginMessagePart3_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, STRING, text, 1)
#define CannedMessagePluginMessagePart3_CALLBACK NULL
#define CannedMessagePluginMessagePart3_DEFAULT NULL
#define CannedMessagePluginMessagePart4_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, STRING, text, 1)
#define CannedMessagePluginMessagePart4_CALLBACK NULL
#define CannedMessagePluginMessagePart4_DEFAULT NULL
#define CannedMessagePluginMessagePart5_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, STRING, text, 1)
#define CannedMessagePluginMessagePart5_CALLBACK NULL
#define CannedMessagePluginMessagePart5_DEFAULT NULL
extern const pb_msgdesc_t CannedMessagePluginMessagePart1_msg;
extern const pb_msgdesc_t CannedMessagePluginMessagePart2_msg;
extern const pb_msgdesc_t CannedMessagePluginMessagePart3_msg;
extern const pb_msgdesc_t CannedMessagePluginMessagePart4_msg;
extern const pb_msgdesc_t CannedMessagePluginMessagePart5_msg;
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
#define CannedMessagePluginMessagePart1_fields &CannedMessagePluginMessagePart1_msg
#define CannedMessagePluginMessagePart2_fields &CannedMessagePluginMessagePart2_msg
#define CannedMessagePluginMessagePart3_fields &CannedMessagePluginMessagePart3_msg
#define CannedMessagePluginMessagePart4_fields &CannedMessagePluginMessagePart4_msg
#define CannedMessagePluginMessagePart5_fields &CannedMessagePluginMessagePart5_msg
/* Maximum encoded size of messages (where known) */
#define CannedMessagePluginMessagePart1_size 202
#define CannedMessagePluginMessagePart2_size 202
#define CannedMessagePluginMessagePart3_size 202
#define CannedMessagePluginMessagePart4_size 202
#define CannedMessagePluginMessagePart5_size 202
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif

View File

@@ -43,6 +43,11 @@ typedef struct _DeviceState {
uint32_t version; uint32_t version;
bool no_save; bool no_save;
bool did_gps_reset; bool did_gps_reset;
char canned_message_plugin_message_part1[200];
char canned_message_plugin_message_part2[200];
char canned_message_plugin_message_part3[200];
char canned_message_plugin_message_part4[200];
char canned_message_plugin_message_part5[200];
} DeviceState; } DeviceState;
@@ -53,11 +58,11 @@ extern "C" {
/* Initializer values for message structs */ /* Initializer values for message structs */
#define LegacyRadioConfig_init_default {false, LegacyRadioConfig_LegacyPreferences_init_default} #define LegacyRadioConfig_init_default {false, LegacyRadioConfig_LegacyPreferences_init_default}
#define LegacyRadioConfig_LegacyPreferences_init_default {_RegionCode_MIN} #define LegacyRadioConfig_LegacyPreferences_init_default {_RegionCode_MIN}
#define DeviceState_init_default {false, LegacyRadioConfig_init_default, false, MyNodeInfo_init_default, false, User_init_default, 0, {NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default}, 0, {MeshPacket_init_default}, false, MeshPacket_init_default, 0, 0, 0} #define DeviceState_init_default {false, LegacyRadioConfig_init_default, false, MyNodeInfo_init_default, false, User_init_default, 0, {NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default}, 0, {MeshPacket_init_default}, false, MeshPacket_init_default, 0, 0, 0, "", "", "", "", ""}
#define ChannelFile_init_default {0, {Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default}} #define ChannelFile_init_default {0, {Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default}}
#define LegacyRadioConfig_init_zero {false, LegacyRadioConfig_LegacyPreferences_init_zero} #define LegacyRadioConfig_init_zero {false, LegacyRadioConfig_LegacyPreferences_init_zero}
#define LegacyRadioConfig_LegacyPreferences_init_zero {_RegionCode_MIN} #define LegacyRadioConfig_LegacyPreferences_init_zero {_RegionCode_MIN}
#define DeviceState_init_zero {false, LegacyRadioConfig_init_zero, false, MyNodeInfo_init_zero, false, User_init_zero, 0, {NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero}, 0, {MeshPacket_init_zero}, false, MeshPacket_init_zero, 0, 0, 0} #define DeviceState_init_zero {false, LegacyRadioConfig_init_zero, false, MyNodeInfo_init_zero, false, User_init_zero, 0, {NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero}, 0, {MeshPacket_init_zero}, false, MeshPacket_init_zero, 0, 0, 0, "", "", "", "", ""}
#define ChannelFile_init_zero {0, {Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero}} #define ChannelFile_init_zero {0, {Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero}}
/* Field tags (for use in manual encoding/decoding) */ /* Field tags (for use in manual encoding/decoding) */
@@ -73,6 +78,11 @@ extern "C" {
#define DeviceState_version_tag 8 #define DeviceState_version_tag 8
#define DeviceState_no_save_tag 9 #define DeviceState_no_save_tag 9
#define DeviceState_did_gps_reset_tag 11 #define DeviceState_did_gps_reset_tag 11
#define DeviceState_canned_message_plugin_message_part1_tag 13
#define DeviceState_canned_message_plugin_message_part2_tag 14
#define DeviceState_canned_message_plugin_message_part3_tag 15
#define DeviceState_canned_message_plugin_message_part4_tag 16
#define DeviceState_canned_message_plugin_message_part5_tag 17
/* Struct field encoding specification for nanopb */ /* Struct field encoding specification for nanopb */
#define LegacyRadioConfig_FIELDLIST(X, a) \ #define LegacyRadioConfig_FIELDLIST(X, a) \
@@ -95,7 +105,12 @@ X(a, STATIC, REPEATED, MESSAGE, receive_queue, 5) \
X(a, STATIC, OPTIONAL, MESSAGE, rx_text_message, 7) \ X(a, STATIC, OPTIONAL, MESSAGE, rx_text_message, 7) \
X(a, STATIC, SINGULAR, UINT32, version, 8) \ X(a, STATIC, SINGULAR, UINT32, version, 8) \
X(a, STATIC, SINGULAR, BOOL, no_save, 9) \ X(a, STATIC, SINGULAR, BOOL, no_save, 9) \
X(a, STATIC, SINGULAR, BOOL, did_gps_reset, 11) X(a, STATIC, SINGULAR, BOOL, did_gps_reset, 11) \
X(a, STATIC, SINGULAR, STRING, canned_message_plugin_message_part1, 13) \
X(a, STATIC, SINGULAR, STRING, canned_message_plugin_message_part2, 14) \
X(a, STATIC, SINGULAR, STRING, canned_message_plugin_message_part3, 15) \
X(a, STATIC, SINGULAR, STRING, canned_message_plugin_message_part4, 16) \
X(a, STATIC, SINGULAR, STRING, canned_message_plugin_message_part5, 17)
#define DeviceState_CALLBACK NULL #define DeviceState_CALLBACK NULL
#define DeviceState_DEFAULT NULL #define DeviceState_DEFAULT NULL
#define DeviceState_legacyRadio_MSGTYPE LegacyRadioConfig #define DeviceState_legacyRadio_MSGTYPE LegacyRadioConfig
@@ -125,7 +140,7 @@ extern const pb_msgdesc_t ChannelFile_msg;
/* Maximum encoded size of messages (where known) */ /* Maximum encoded size of messages (where known) */
#define LegacyRadioConfig_size 4 #define LegacyRadioConfig_size 4
#define LegacyRadioConfig_LegacyPreferences_size 2 #define LegacyRadioConfig_LegacyPreferences_size 2
#define DeviceState_size 9967 #define DeviceState_size 11014
#define ChannelFile_size 832 #define ChannelFile_size 832
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -14,6 +14,9 @@ typedef struct _EnvironmentalMeasurement {
float temperature; float temperature;
float relative_humidity; float relative_humidity;
float barometric_pressure; float barometric_pressure;
float gas_resistance;
float voltage;
float current;
} EnvironmentalMeasurement; } EnvironmentalMeasurement;
@@ -22,19 +25,25 @@ extern "C" {
#endif #endif
/* Initializer values for message structs */ /* Initializer values for message structs */
#define EnvironmentalMeasurement_init_default {0, 0, 0} #define EnvironmentalMeasurement_init_default {0, 0, 0, 0, 0, 0}
#define EnvironmentalMeasurement_init_zero {0, 0, 0} #define EnvironmentalMeasurement_init_zero {0, 0, 0, 0, 0, 0}
/* Field tags (for use in manual encoding/decoding) */ /* Field tags (for use in manual encoding/decoding) */
#define EnvironmentalMeasurement_temperature_tag 1 #define EnvironmentalMeasurement_temperature_tag 1
#define EnvironmentalMeasurement_relative_humidity_tag 2 #define EnvironmentalMeasurement_relative_humidity_tag 2
#define EnvironmentalMeasurement_barometric_pressure_tag 3 #define EnvironmentalMeasurement_barometric_pressure_tag 3
#define EnvironmentalMeasurement_gas_resistance_tag 4
#define EnvironmentalMeasurement_voltage_tag 5
#define EnvironmentalMeasurement_current_tag 6
/* Struct field encoding specification for nanopb */ /* Struct field encoding specification for nanopb */
#define EnvironmentalMeasurement_FIELDLIST(X, a) \ #define EnvironmentalMeasurement_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, FLOAT, temperature, 1) \ X(a, STATIC, SINGULAR, FLOAT, temperature, 1) \
X(a, STATIC, SINGULAR, FLOAT, relative_humidity, 2) \ X(a, STATIC, SINGULAR, FLOAT, relative_humidity, 2) \
X(a, STATIC, SINGULAR, FLOAT, barometric_pressure, 3) X(a, STATIC, SINGULAR, FLOAT, barometric_pressure, 3) \
X(a, STATIC, SINGULAR, FLOAT, gas_resistance, 4) \
X(a, STATIC, SINGULAR, FLOAT, voltage, 5) \
X(a, STATIC, SINGULAR, FLOAT, current, 6)
#define EnvironmentalMeasurement_CALLBACK NULL #define EnvironmentalMeasurement_CALLBACK NULL
#define EnvironmentalMeasurement_DEFAULT NULL #define EnvironmentalMeasurement_DEFAULT NULL
@@ -44,7 +53,7 @@ extern const pb_msgdesc_t EnvironmentalMeasurement_msg;
#define EnvironmentalMeasurement_fields &EnvironmentalMeasurement_msg #define EnvironmentalMeasurement_fields &EnvironmentalMeasurement_msg
/* Maximum encoded size of messages (where known) */ /* Maximum encoded size of messages (where known) */
#define EnvironmentalMeasurement_size 15 #define EnvironmentalMeasurement_size 30
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */

View File

@@ -31,7 +31,9 @@ typedef enum _HardwareModel {
HardwareModel_NRF52_UNKNOWN = 36, HardwareModel_NRF52_UNKNOWN = 36,
HardwareModel_PORTDUINO = 37, HardwareModel_PORTDUINO = 37,
HardwareModel_ANDROID_SIM = 38, HardwareModel_ANDROID_SIM = 38,
HardwareModel_DIY_V1 = 39 HardwareModel_DIY_V1 = 39,
HardwareModel_RAK11200 = 40,
HardwareModel_PRIVATE_HW = 255
} HardwareModel; } HardwareModel;
typedef enum _Team { typedef enum _Team {
@@ -136,6 +138,8 @@ typedef struct _Data {
uint32_t dest; uint32_t dest;
uint32_t source; uint32_t source;
uint32_t request_id; uint32_t request_id;
uint32_t reply_id;
bool is_tapback;
} Data; } Data;
typedef struct _LogRecord { typedef struct _LogRecord {
@@ -166,6 +170,7 @@ typedef struct _MyNodeInfo {
uint32_t air_period_rx[24]; uint32_t air_period_rx[24];
bool has_wifi; bool has_wifi;
float channel_utilization; float channel_utilization;
float air_util_tx;
} MyNodeInfo; } MyNodeInfo;
typedef struct _Position { typedef struct _Position {
@@ -235,8 +240,6 @@ typedef struct _MeshPacket {
MeshPacket_Priority priority; MeshPacket_Priority priority;
int32_t rx_rssi; int32_t rx_rssi;
MeshPacket_Delayed delayed; MeshPacket_Delayed delayed;
uint32_t reply_id;
bool is_tapback;
} MeshPacket; } MeshPacket;
typedef struct _NodeInfo { typedef struct _NodeInfo {
@@ -284,8 +287,8 @@ typedef struct _ToRadio {
/* Helper constants for enums */ /* Helper constants for enums */
#define _HardwareModel_MIN HardwareModel_UNSET #define _HardwareModel_MIN HardwareModel_UNSET
#define _HardwareModel_MAX HardwareModel_DIY_V1 #define _HardwareModel_MAX HardwareModel_PRIVATE_HW
#define _HardwareModel_ARRAYSIZE ((HardwareModel)(HardwareModel_DIY_V1+1)) #define _HardwareModel_ARRAYSIZE ((HardwareModel)(HardwareModel_PRIVATE_HW+1))
#define _Team_MIN Team_CLEAR #define _Team_MIN Team_CLEAR
#define _Team_MAX Team_BROWN #define _Team_MAX Team_BROWN
@@ -333,10 +336,10 @@ extern "C" {
#define User_init_default {"", "", "", {0}, _HardwareModel_MIN, 0, _Team_MIN, 0, 0, 0} #define User_init_default {"", "", "", {0}, _HardwareModel_MIN, 0, _Team_MIN, 0, 0, 0}
#define RouteDiscovery_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}} #define RouteDiscovery_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}}
#define Routing_init_default {0, {RouteDiscovery_init_default}} #define Routing_init_default {0, {RouteDiscovery_init_default}}
#define Data_init_default {_PortNum_MIN, {0, {0}}, 0, 0, 0, 0} #define Data_init_default {_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0}
#define MeshPacket_init_default {0, 0, 0, 0, {Data_init_default}, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN, 0, _MeshPacket_Delayed_MIN, 0, 0} #define MeshPacket_init_default {0, 0, 0, 0, {Data_init_default}, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN, 0, _MeshPacket_Delayed_MIN}
#define NodeInfo_init_default {0, false, User_init_default, false, Position_init_default, 0, 0} #define NodeInfo_init_default {0, false, User_init_default, false, Position_init_default, 0, 0}
#define MyNodeInfo_init_default {0, 0, 0, "", "", "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0} #define MyNodeInfo_init_default {0, 0, 0, "", "", "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0}
#define LogRecord_init_default {"", 0, "", _LogRecord_Level_MIN} #define LogRecord_init_default {"", 0, "", _LogRecord_Level_MIN}
#define FromRadio_init_default {0, 0, {MyNodeInfo_init_default}} #define FromRadio_init_default {0, 0, {MyNodeInfo_init_default}}
#define ToRadio_init_default {0, {MeshPacket_init_default}} #define ToRadio_init_default {0, {MeshPacket_init_default}}
@@ -345,10 +348,10 @@ extern "C" {
#define User_init_zero {"", "", "", {0}, _HardwareModel_MIN, 0, _Team_MIN, 0, 0, 0} #define User_init_zero {"", "", "", {0}, _HardwareModel_MIN, 0, _Team_MIN, 0, 0, 0}
#define RouteDiscovery_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}} #define RouteDiscovery_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}}
#define Routing_init_zero {0, {RouteDiscovery_init_zero}} #define Routing_init_zero {0, {RouteDiscovery_init_zero}}
#define Data_init_zero {_PortNum_MIN, {0, {0}}, 0, 0, 0, 0} #define Data_init_zero {_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0}
#define MeshPacket_init_zero {0, 0, 0, 0, {Data_init_zero}, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN, 0, _MeshPacket_Delayed_MIN, 0, 0} #define MeshPacket_init_zero {0, 0, 0, 0, {Data_init_zero}, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN, 0, _MeshPacket_Delayed_MIN}
#define NodeInfo_init_zero {0, false, User_init_zero, false, Position_init_zero, 0, 0} #define NodeInfo_init_zero {0, false, User_init_zero, false, Position_init_zero, 0, 0}
#define MyNodeInfo_init_zero {0, 0, 0, "", "", "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0} #define MyNodeInfo_init_zero {0, 0, 0, "", "", "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0}
#define LogRecord_init_zero {"", 0, "", _LogRecord_Level_MIN} #define LogRecord_init_zero {"", 0, "", _LogRecord_Level_MIN}
#define FromRadio_init_zero {0, 0, {MyNodeInfo_init_zero}} #define FromRadio_init_zero {0, 0, {MyNodeInfo_init_zero}}
#define ToRadio_init_zero {0, {MeshPacket_init_zero}} #define ToRadio_init_zero {0, {MeshPacket_init_zero}}
@@ -361,6 +364,8 @@ extern "C" {
#define Data_dest_tag 4 #define Data_dest_tag 4
#define Data_source_tag 5 #define Data_source_tag 5
#define Data_request_id_tag 6 #define Data_request_id_tag 6
#define Data_reply_id_tag 7
#define Data_is_tapback_tag 8
#define LogRecord_message_tag 1 #define LogRecord_message_tag 1
#define LogRecord_time_tag 2 #define LogRecord_time_tag 2
#define LogRecord_source_tag 3 #define LogRecord_source_tag 3
@@ -383,6 +388,7 @@ extern "C" {
#define MyNodeInfo_air_period_rx_tag 17 #define MyNodeInfo_air_period_rx_tag 17
#define MyNodeInfo_has_wifi_tag 18 #define MyNodeInfo_has_wifi_tag 18
#define MyNodeInfo_channel_utilization_tag 19 #define MyNodeInfo_channel_utilization_tag 19
#define MyNodeInfo_air_util_tx_tag 20
#define Position_latitude_i_tag 1 #define Position_latitude_i_tag 1
#define Position_longitude_i_tag 2 #define Position_longitude_i_tag 2
#define Position_altitude_tag 3 #define Position_altitude_tag 3
@@ -432,8 +438,6 @@ extern "C" {
#define MeshPacket_priority_tag 12 #define MeshPacket_priority_tag 12
#define MeshPacket_rx_rssi_tag 13 #define MeshPacket_rx_rssi_tag 13
#define MeshPacket_delayed_tag 15 #define MeshPacket_delayed_tag 15
#define MeshPacket_reply_id_tag 16
#define MeshPacket_is_tapback_tag 17
#define NodeInfo_num_tag 1 #define NodeInfo_num_tag 1
#define NodeInfo_user_tag 2 #define NodeInfo_user_tag 2
#define NodeInfo_position_tag 3 #define NodeInfo_position_tag 3
@@ -516,7 +520,9 @@ X(a, STATIC, SINGULAR, BYTES, payload, 2) \
X(a, STATIC, SINGULAR, BOOL, want_response, 3) \ X(a, STATIC, SINGULAR, BOOL, want_response, 3) \
X(a, STATIC, SINGULAR, FIXED32, dest, 4) \ X(a, STATIC, SINGULAR, FIXED32, dest, 4) \
X(a, STATIC, SINGULAR, FIXED32, source, 5) \ X(a, STATIC, SINGULAR, FIXED32, source, 5) \
X(a, STATIC, SINGULAR, FIXED32, request_id, 6) X(a, STATIC, SINGULAR, FIXED32, request_id, 6) \
X(a, STATIC, SINGULAR, FIXED32, reply_id, 7) \
X(a, STATIC, SINGULAR, BOOL, is_tapback, 8)
#define Data_CALLBACK NULL #define Data_CALLBACK NULL
#define Data_DEFAULT NULL #define Data_DEFAULT NULL
@@ -533,9 +539,7 @@ X(a, STATIC, SINGULAR, UINT32, hop_limit, 10) \
X(a, STATIC, SINGULAR, BOOL, want_ack, 11) \ X(a, STATIC, SINGULAR, BOOL, want_ack, 11) \
X(a, STATIC, SINGULAR, UENUM, priority, 12) \ X(a, STATIC, SINGULAR, UENUM, priority, 12) \
X(a, STATIC, SINGULAR, INT32, rx_rssi, 13) \ X(a, STATIC, SINGULAR, INT32, rx_rssi, 13) \
X(a, STATIC, SINGULAR, UENUM, delayed, 15) \ X(a, STATIC, SINGULAR, UENUM, delayed, 15)
X(a, STATIC, SINGULAR, FIXED32, reply_id, 16) \
X(a, STATIC, SINGULAR, BOOL, is_tapback, 17)
#define MeshPacket_CALLBACK NULL #define MeshPacket_CALLBACK NULL
#define MeshPacket_DEFAULT NULL #define MeshPacket_DEFAULT NULL
#define MeshPacket_payloadVariant_decoded_MSGTYPE Data #define MeshPacket_payloadVariant_decoded_MSGTYPE Data
@@ -569,7 +573,8 @@ X(a, STATIC, SINGULAR, UINT32, max_channels, 15) \
X(a, STATIC, REPEATED, UINT32, air_period_tx, 16) \ X(a, STATIC, REPEATED, UINT32, air_period_tx, 16) \
X(a, STATIC, REPEATED, UINT32, air_period_rx, 17) \ X(a, STATIC, REPEATED, UINT32, air_period_rx, 17) \
X(a, STATIC, SINGULAR, BOOL, has_wifi, 18) \ X(a, STATIC, SINGULAR, BOOL, has_wifi, 18) \
X(a, STATIC, SINGULAR, FLOAT, channel_utilization, 19) X(a, STATIC, SINGULAR, FLOAT, channel_utilization, 19) \
X(a, STATIC, SINGULAR, FLOAT, air_util_tx, 20)
#define MyNodeInfo_CALLBACK NULL #define MyNodeInfo_CALLBACK NULL
#define MyNodeInfo_DEFAULT NULL #define MyNodeInfo_DEFAULT NULL
@@ -641,16 +646,16 @@ extern const pb_msgdesc_t ToRadio_PeerInfo_msg;
/* Maximum encoded size of messages (where known) */ /* Maximum encoded size of messages (where known) */
#define Position_size 153 #define Position_size 153
#define User_size 96 #define User_size 97
#define RouteDiscovery_size 40 #define RouteDiscovery_size 40
#define Routing_size 42 #define Routing_size 42
#define Data_size 260 #define Data_size 267
#define MeshPacket_size 320 #define MeshPacket_size 318
#define NodeInfo_size 270 #define NodeInfo_size 271
#define MyNodeInfo_size 451 #define MyNodeInfo_size 457
#define LogRecord_size 81 #define LogRecord_size 81
#define FromRadio_size 460 #define FromRadio_size 466
#define ToRadio_size 323 #define ToRadio_size 321
#define ToRadio_PeerInfo_size 8 #define ToRadio_PeerInfo_size 8
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -20,3 +20,4 @@ PB_BIND(RadioConfig_UserPreferences, RadioConfig_UserPreferences, 2)

View File

@@ -79,9 +79,25 @@ typedef enum _PositionFlags {
PositionFlags_POS_TIMESTAMP = 256 PositionFlags_POS_TIMESTAMP = 256
} PositionFlags; } PositionFlags;
typedef enum _InputEventChar {
InputEventChar_KEY_NONE = 0,
InputEventChar_KEY_UP = 17,
InputEventChar_KEY_DOWN = 18,
InputEventChar_KEY_LEFT = 19,
InputEventChar_KEY_RIGHT = 20,
InputEventChar_KEY_SELECT = 10,
InputEventChar_KEY_BACK = 27,
InputEventChar_KEY_CANCEL = 24
} InputEventChar;
typedef enum _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType { typedef enum _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType {
RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT11 = 0, RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT11 = 0,
RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DS18B20 = 1 RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DS18B20 = 1,
RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT12 = 2,
RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT21 = 3,
RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT22 = 4,
RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_BME280 = 5,
RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_BME680 = 6
} RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType; } RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType;
/* Struct definitions */ /* Struct definitions */
@@ -157,6 +173,18 @@ typedef struct _RadioConfig_UserPreferences {
char mqtt_password[32]; char mqtt_password[32];
bool is_lora_tx_disabled; bool is_lora_tx_disabled;
bool is_power_saving; bool is_power_saving;
bool rotary1_enabled;
uint32_t rotary1_pin_a;
uint32_t rotary1_pin_b;
uint32_t rotary1_pin_press;
InputEventChar rotary1_event_cw;
InputEventChar rotary1_event_ccw;
InputEventChar rotary1_event_press;
bool canned_message_plugin_enabled;
char canned_message_plugin_allow_input_source[16];
char canned_message_plugin_messages[200];
bool canned_message_plugin_send_bell;
bool mqtt_encryption_enabled;
} RadioConfig_UserPreferences; } RadioConfig_UserPreferences;
typedef struct _RadioConfig { typedef struct _RadioConfig {
@@ -190,9 +218,13 @@ typedef struct _RadioConfig {
#define _PositionFlags_MAX PositionFlags_POS_TIMESTAMP #define _PositionFlags_MAX PositionFlags_POS_TIMESTAMP
#define _PositionFlags_ARRAYSIZE ((PositionFlags)(PositionFlags_POS_TIMESTAMP+1)) #define _PositionFlags_ARRAYSIZE ((PositionFlags)(PositionFlags_POS_TIMESTAMP+1))
#define _InputEventChar_MIN InputEventChar_KEY_NONE
#define _InputEventChar_MAX InputEventChar_KEY_BACK
#define _InputEventChar_ARRAYSIZE ((InputEventChar)(InputEventChar_KEY_BACK+1))
#define _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MIN RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT11 #define _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MIN RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT11
#define _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MAX RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DS18B20 #define _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MAX RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_BME680
#define _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_ARRAYSIZE ((RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType)(RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DS18B20+1)) #define _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_ARRAYSIZE ((RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType)(RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_BME680+1))
#ifdef __cplusplus #ifdef __cplusplus
@@ -201,9 +233,9 @@ extern "C" {
/* Initializer values for message structs */ /* Initializer values for message structs */
#define RadioConfig_init_default {false, RadioConfig_UserPreferences_init_default} #define RadioConfig_init_default {false, RadioConfig_UserPreferences_init_default}
#define RadioConfig_UserPreferences_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, 0, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, "", 0, _GpsCoordinateFormat_MIN, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MIN, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, 0} #define RadioConfig_UserPreferences_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, 0, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, "", 0, _GpsCoordinateFormat_MIN, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MIN, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, 0, 0, 0, 0, 0, _InputEventChar_MIN, _InputEventChar_MIN, _InputEventChar_MIN, 0, "", "", 0, 0}
#define RadioConfig_init_zero {false, RadioConfig_UserPreferences_init_zero} #define RadioConfig_init_zero {false, RadioConfig_UserPreferences_init_zero}
#define RadioConfig_UserPreferences_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, 0, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, "", 0, _GpsCoordinateFormat_MIN, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MIN, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, 0} #define RadioConfig_UserPreferences_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, 0, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, "", 0, _GpsCoordinateFormat_MIN, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MIN, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, 0, 0, 0, 0, 0, _InputEventChar_MIN, _InputEventChar_MIN, _InputEventChar_MIN, 0, "", "", 0, 0}
/* Field tags (for use in manual encoding/decoding) */ /* Field tags (for use in manual encoding/decoding) */
#define RadioConfig_UserPreferences_position_broadcast_secs_tag 1 #define RadioConfig_UserPreferences_position_broadcast_secs_tag 1
@@ -276,6 +308,18 @@ extern "C" {
#define RadioConfig_UserPreferences_mqtt_password_tag 156 #define RadioConfig_UserPreferences_mqtt_password_tag 156
#define RadioConfig_UserPreferences_is_lora_tx_disabled_tag 157 #define RadioConfig_UserPreferences_is_lora_tx_disabled_tag 157
#define RadioConfig_UserPreferences_is_power_saving_tag 158 #define RadioConfig_UserPreferences_is_power_saving_tag 158
#define RadioConfig_UserPreferences_rotary1_enabled_tag 160
#define RadioConfig_UserPreferences_rotary1_pin_a_tag 161
#define RadioConfig_UserPreferences_rotary1_pin_b_tag 162
#define RadioConfig_UserPreferences_rotary1_pin_press_tag 163
#define RadioConfig_UserPreferences_rotary1_event_cw_tag 164
#define RadioConfig_UserPreferences_rotary1_event_ccw_tag 165
#define RadioConfig_UserPreferences_rotary1_event_press_tag 166
#define RadioConfig_UserPreferences_canned_message_plugin_enabled_tag 170
#define RadioConfig_UserPreferences_canned_message_plugin_allow_input_source_tag 171
#define RadioConfig_UserPreferences_canned_message_plugin_messages_tag 172
#define RadioConfig_UserPreferences_canned_message_plugin_send_bell_tag 173
#define RadioConfig_UserPreferences_mqtt_encryption_enabled_tag 174
#define RadioConfig_preferences_tag 1 #define RadioConfig_preferences_tag 1
/* Struct field encoding specification for nanopb */ /* Struct field encoding specification for nanopb */
@@ -355,7 +399,19 @@ X(a, STATIC, SINGULAR, UINT32, hop_limit, 154) \
X(a, STATIC, SINGULAR, STRING, mqtt_username, 155) \ X(a, STATIC, SINGULAR, STRING, mqtt_username, 155) \
X(a, STATIC, SINGULAR, STRING, mqtt_password, 156) \ X(a, STATIC, SINGULAR, STRING, mqtt_password, 156) \
X(a, STATIC, SINGULAR, BOOL, is_lora_tx_disabled, 157) \ X(a, STATIC, SINGULAR, BOOL, is_lora_tx_disabled, 157) \
X(a, STATIC, SINGULAR, BOOL, is_power_saving, 158) X(a, STATIC, SINGULAR, BOOL, is_power_saving, 158) \
X(a, STATIC, SINGULAR, BOOL, rotary1_enabled, 160) \
X(a, STATIC, SINGULAR, UINT32, rotary1_pin_a, 161) \
X(a, STATIC, SINGULAR, UINT32, rotary1_pin_b, 162) \
X(a, STATIC, SINGULAR, UINT32, rotary1_pin_press, 163) \
X(a, STATIC, SINGULAR, UENUM, rotary1_event_cw, 164) \
X(a, STATIC, SINGULAR, UENUM, rotary1_event_ccw, 165) \
X(a, STATIC, SINGULAR, UENUM, rotary1_event_press, 166) \
X(a, STATIC, SINGULAR, BOOL, canned_message_plugin_enabled, 170) \
X(a, STATIC, SINGULAR, STRING, canned_message_plugin_allow_input_source, 171) \
X(a, STATIC, SINGULAR, STRING, canned_message_plugin_messages, 172) \
X(a, STATIC, SINGULAR, BOOL, canned_message_plugin_send_bell, 173) \
X(a, STATIC, SINGULAR, BOOL, mqtt_encryption_enabled, 174)
#define RadioConfig_UserPreferences_CALLBACK NULL #define RadioConfig_UserPreferences_CALLBACK NULL
#define RadioConfig_UserPreferences_DEFAULT NULL #define RadioConfig_UserPreferences_DEFAULT NULL
@@ -367,8 +423,8 @@ extern const pb_msgdesc_t RadioConfig_UserPreferences_msg;
#define RadioConfig_UserPreferences_fields &RadioConfig_UserPreferences_msg #define RadioConfig_UserPreferences_fields &RadioConfig_UserPreferences_msg
/* Maximum encoded size of messages (where known) */ /* Maximum encoded size of messages (where known) */
#define RadioConfig_size 532 #define RadioConfig_size 795
#define RadioConfig_UserPreferences_size 529 #define RadioConfig_UserPreferences_size 792
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */

View File

@@ -624,6 +624,8 @@ void handleReport(HTTPRequest *req, HTTPResponse *res)
} }
res->println("],"); res->println("],");
res->printf("\"channel_utilization\": %3.2f%,\n", airTime->channelUtilizationPercent());
res->printf("\"utilization_tx\": %3.2f%,\n", airTime->utilizationTXPercent());
res->printf("\"seconds_since_boot\": %u,\n", airTime->getSecondsSinceBoot()); res->printf("\"seconds_since_boot\": %u,\n", airTime->getSecondsSinceBoot());
res->printf("\"seconds_per_period\": %u,\n", airTime->getSecondsPerPeriod()); res->printf("\"seconds_per_period\": %u,\n", airTime->getSecondsPerPeriod());
res->printf("\"periods_to_log\": %u\n", airTime->getPeriodsToLog()); res->printf("\"periods_to_log\": %u\n", airTime->getPeriodsToLog());
@@ -661,7 +663,6 @@ void handleReport(HTTPRequest *req, HTTPResponse *res)
res->println("},"); res->println("},");
res->println("\"device\": {"); res->println("\"device\": {");
res->printf("\"channel_utilization\": %3.2f%,\n", airTime->channelUtilizationPercent());
res->printf("\"reboot_counter\": %d\n", myNodeInfo.reboot_count); res->printf("\"reboot_counter\": %d\n", myNodeInfo.reboot_count);
res->println("},"); res->println("},");

View File

@@ -36,7 +36,7 @@ class HttpAPI : public PhoneAPI
protected: protected:
/// Check the current underlying physical link to see if the client is currently connected /// Check the current underlying physical link to see if the client is currently connected
virtual bool checkIsConnected() { return true; } // FIXME, be smarter about this virtual bool checkIsConnected() override { return true; } // FIXME, be smarter about this
}; };

View File

@@ -130,8 +130,8 @@ static void taskCreateCert(void *parameter)
void createSSLCert() void createSSLCert()
{ {
bool runLoop = false;
if (isWifiAvailable() && !isCertReady) { if (isWifiAvailable() && !isCertReady) {
bool runLoop = false;
// Create a new process just to handle creating the cert. // Create a new process just to handle creating the cert.
// This is a workaround for Bug: https://github.com/fhessel/esp32_https_server/issues/48 // This is a workaround for Bug: https://github.com/fhessel/esp32_https_server/issues/48

View File

@@ -16,7 +16,7 @@ class WebServerThread : private concurrency::OSThread
uint32_t requestRestart = 0; uint32_t requestRestart = 0;
protected: protected:
virtual int32_t runOnce(); virtual int32_t runOnce() override;
}; };
extern WebServerThread *webServerThread; extern WebServerThread *webServerThread;

View File

@@ -13,7 +13,7 @@ class WiFiServerAPI : public StreamAPI
WiFiClient client; WiFiClient client;
public: public:
WiFiServerAPI(WiFiClient &_client); explicit WiFiServerAPI(WiFiClient &_client);
virtual ~WiFiServerAPI(); virtual ~WiFiServerAPI();
@@ -23,12 +23,12 @@ class WiFiServerAPI : public StreamAPI
protected: protected:
/// We override this method to prevent publishing EVENT_SERIAL_CONNECTED/DISCONNECTED for wifi links (we want the board to /// We override this method to prevent publishing EVENT_SERIAL_CONNECTED/DISCONNECTED for wifi links (we want the board to
/// stay in the POWERED state to prevent disabling wifi) /// stay in the POWERED state to prevent disabling wifi)
virtual void onConnectionChanged(bool connected) {} virtual void onConnectionChanged(bool connected) override {}
virtual int32_t runOnce(); // Check for dropped client connections virtual int32_t runOnce() override; // Check for dropped client connections
/// Check the current underlying physical link to see if the client is currently connected /// Check the current underlying physical link to see if the client is currently connected
virtual bool checkIsConnected(); virtual bool checkIsConnected() override;
}; };
/** /**
@@ -52,7 +52,7 @@ class WiFiServerPort : public WiFiServer, private concurrency::OSThread
static void debugOut(char c); static void debugOut(char c);
protected: protected:
int32_t runOnce(); int32_t runOnce() override;
}; };
void initApiServer(); void initApiServer();

View File

@@ -40,7 +40,7 @@ class MQTT : private concurrency::OSThread
void reconnect(); void reconnect();
protected: protected:
virtual int32_t runOnce(); virtual int32_t runOnce() override;
private: private:
/** return true if we have a channel that wants uplink/downlink /** return true if we have a channel that wants uplink/downlink

View File

@@ -10,10 +10,10 @@ protected:
/** /**
* Subclasses can use this as a hook to provide custom notifications for their transport (i.e. bluetooth notifies) * Subclasses can use this as a hook to provide custom notifications for their transport (i.e. bluetooth notifies)
*/ */
virtual void onNowHasData(uint32_t fromRadioNum); virtual void onNowHasData(uint32_t fromRadioNum) override;
/// Check the current underlying physical link to see if the client is currently connected /// Check the current underlying physical link to see if the client is currently connected
virtual bool checkIsConnected(); virtual bool checkIsConnected() override;
}; };
extern PhoneAPI *bluetoothPhoneAPI; extern PhoneAPI *bluetoothPhoneAPI;

View File

@@ -28,7 +28,7 @@ class BluetoothPhoneAPI : public PhoneAPI
/** /**
* Subclasses can use this as a hook to provide custom notifications for their transport (i.e. bluetooth notifies) * Subclasses can use this as a hook to provide custom notifications for their transport (i.e. bluetooth notifies)
*/ */
virtual void onNowHasData(uint32_t fromRadioNum) virtual void onNowHasData(uint32_t fromRadioNum) override
{ {
PhoneAPI::onNowHasData(fromRadioNum); PhoneAPI::onNowHasData(fromRadioNum);
@@ -37,7 +37,7 @@ class BluetoothPhoneAPI : public PhoneAPI
} }
/// Check the current underlying physical link to see if the client is currently connected /// Check the current underlying physical link to see if the client is currently connected
virtual bool checkIsConnected() { virtual bool checkIsConnected() override {
return bleConnected; return bleConnected;
} }
}; };
@@ -265,4 +265,4 @@ void NRF52Bluetooth::setup()
void updateBatteryLevel(uint8_t level) void updateBatteryLevel(uint8_t level)
{ {
blebas.write(level); blebas.write(level);
} }

View File

@@ -17,7 +17,7 @@ class NRF52CryptoEngine : public CryptoEngine
* *
* @param bytes is updated in place * @param bytes is updated in place
*/ */
virtual void encrypt(uint32_t fromNode, uint64_t packetNum, size_t numBytes, uint8_t *bytes) virtual void encrypt(uint32_t fromNode, uint64_t packetNum, size_t numBytes, uint8_t *bytes) override
{ {
// DEBUG_MSG("NRF52 encrypt!\n"); // DEBUG_MSG("NRF52 encrypt!\n");
@@ -31,7 +31,7 @@ class NRF52CryptoEngine : public CryptoEngine
} }
} }
virtual void decrypt(uint32_t fromNode, uint64_t packetNum, size_t numBytes, uint8_t *bytes) virtual void decrypt(uint32_t fromNode, uint64_t packetNum, size_t numBytes, uint8_t *bytes) override
{ {
// DEBUG_MSG("NRF52 decrypt!\n"); // DEBUG_MSG("NRF52 decrypt!\n");

View File

@@ -104,6 +104,12 @@ bool AdminPlugin::handleReceivedProtobuf(const MeshPacket &mp, AdminMessage *r)
rebootAtMsec = (s < 0) ? 0 : (millis() + s * 1000); rebootAtMsec = (s < 0) ? 0 : (millis() + s * 1000);
break; break;
} }
case AdminMessage_shutdown_seconds_tag: {
int32_t s = r->shutdown_seconds;
DEBUG_MSG("Shutdown in %d seconds\n", s);
shutdownAtMsec = (s < 0) ? 0 : (millis() + s * 1000);
break;
}
#ifdef PORTDUINO #ifdef PORTDUINO
case AdminMessage_exit_simulator_tag: case AdminMessage_exit_simulator_tag:

View File

@@ -17,7 +17,7 @@ class AdminPlugin : public ProtobufPlugin<AdminMessage>
@return true if you've guaranteed you've handled this message and no other handlers should be considered for it @return true if you've guaranteed you've handled this message and no other handlers should be considered for it
*/ */
virtual bool handleReceivedProtobuf(const MeshPacket &mp, AdminMessage *p); virtual bool handleReceivedProtobuf(const MeshPacket &mp, AdminMessage *p) override;
private: private:
void handleSetOwner(const User &o); void handleSetOwner(const User &o);
@@ -28,4 +28,4 @@ class AdminPlugin : public ProtobufPlugin<AdminMessage>
void handleGetRadio(const MeshPacket &req); void handleGetRadio(const MeshPacket &req);
}; };
extern AdminPlugin *adminPlugin; extern AdminPlugin *adminPlugin;

View File

@@ -0,0 +1,288 @@
#include "configuration.h"
#include "CannedMessagePlugin.h"
#include "MeshService.h"
// TODO: reuse defined from Screen.cpp
#define FONT_SMALL ArialMT_Plain_10
#define FONT_MEDIUM ArialMT_Plain_16
#define FONT_LARGE ArialMT_Plain_24
// Remove Canned message screen if no action is taken for some milliseconds
#define INACTIVATE_AFTER_MS 20000
CannedMessagePlugin *cannedMessagePlugin;
CannedMessagePlugin::CannedMessagePlugin()
: SinglePortPlugin("canned", PortNum_TEXT_MESSAGE_APP),
concurrency::OSThread("CannedMessagePlugin")
{
if (radioConfig.preferences.canned_message_plugin_enabled)
{
if(this->splitConfiguredMessages() <= 0)
{
radioConfig.preferences.canned_message_plugin_enabled = false;
DEBUG_MSG("CannedMessagePlugin: No messages are configured. Plugin is disabled\n");
return;
}
this->inputObserver.observe(inputBroker);
}
}
/**
* @brief Items in array this->messages will be set to be pointing on the right
* starting points of the string this->messageStore
*
* @return int Returns the number of messages found.
*/
int CannedMessagePlugin::splitConfiguredMessages()
{
int messageIndex = 0;
int i = 0;
strncpy(
this->messageStore,
radioConfig.preferences.canned_message_plugin_messages,
CANNED_MESSAGE_PLUGIN_MESSAGES_SIZE);
this->messages[messageIndex++] =
this->messageStore;
int upTo =
strlen(this->messageStore) - 1;
while (i < upTo)
{
if (this->messageStore[i] == '|')
{
// Message ending found, replace it with string-end character.
this->messageStore[i] = '\0';
DEBUG_MSG("CannedMessage %d is: '%s'\n",
messageIndex-1, this->messages[messageIndex-1]);
if (messageIndex >= CANNED_MESSAGE_PLUGIN_MESSAGE_MAX_COUNT)
{
this->messagesCount = messageIndex;
return this->messagesCount;
}
// Next message starts after pipe (|) just found.
this->messages[messageIndex++] =
(this->messageStore + i + 1);
}
i += 1;
}
if (strlen(this->messages[messageIndex-1]) > 0)
{
DEBUG_MSG("CannedMessage %d is: '%s'\n",
messageIndex-1, this->messages[messageIndex-1]);
this->messagesCount = messageIndex;
}
else
{
this->messagesCount = messageIndex-1;
}
return this->messagesCount;
}
int CannedMessagePlugin::handleInputEvent(const InputEvent *event)
{
if (
(strlen(radioConfig.preferences.canned_message_plugin_allow_input_source) > 0) &&
(strcmp(radioConfig.preferences.canned_message_plugin_allow_input_source, event->source) != 0) &&
(strcmp(radioConfig.preferences.canned_message_plugin_allow_input_source, "_any") != 0))
{
// Event source is not accepted.
return 0;
}
bool validEvent = false;
if (event->inputEvent == static_cast<char>(InputEventChar_KEY_UP))
{
DEBUG_MSG("Canned message event UP\n");
this->runState = CANNED_MESSAGE_RUN_STATE_ACTION_UP;
validEvent = true;
}
if (event->inputEvent == static_cast<char>(InputEventChar_KEY_DOWN))
{
DEBUG_MSG("Canned message event DOWN\n");
this->runState = CANNED_MESSAGE_RUN_STATE_ACTION_DOWN;
validEvent = true;
}
if (event->inputEvent == static_cast<char>(InputEventChar_KEY_SELECT))
{
DEBUG_MSG("Canned message event Select\n");
this->runState = CANNED_MESSAGE_RUN_STATE_ACTION_SELECT;
validEvent = true;
}
if (validEvent)
{
// Let runOnce to be called immediately.
setIntervalFromNow(0);
}
return 0;
}
void CannedMessagePlugin::sendText(NodeNum dest,
const char* message,
bool wantReplies)
{
MeshPacket *p = allocDataPacket();
p->to = dest;
p->want_ack = true;
p->decoded.payload.size = strlen(message);
memcpy(p->decoded.payload.bytes, message, p->decoded.payload.size);
if (radioConfig.preferences.canned_message_plugin_send_bell)
{
p->decoded.payload.bytes[p->decoded.payload.size-1] = 7; // Bell character
p->decoded.payload.bytes[p->decoded.payload.size] = '\0'; // Bell character
p->decoded.payload.size++;
}
// PacketId prevPacketId = p->id; // In case we need it later.
DEBUG_MSG("Sending message id=%d, msg=%.*s\n",
p->id, p->decoded.payload.size, p->decoded.payload.bytes);
service.sendToMesh(p);
}
int32_t CannedMessagePlugin::runOnce()
{
if ((!radioConfig.preferences.canned_message_plugin_enabled)
|| (this->runState == CANNED_MESSAGE_RUN_STATE_INACTIVE))
{
return 30000; // TODO: should return MAX_VAL
}
DEBUG_MSG("Check status\n");
UIFrameEvent e = {false, true};
if (this->runState == CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE)
{
// TODO: might have some feedback of sendig state
this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
e.frameChanged = true;
this->currentMessageIndex = -1;
this->notifyObservers(&e);
}
else if (
(this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE)
&& (millis() - this->lastTouchMillis) > INACTIVATE_AFTER_MS)
{
// Reset plugin
DEBUG_MSG("Reset due the lack of activity.\n");
e.frameChanged = true;
this->currentMessageIndex = -1;
this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
this->notifyObservers(&e);
}
else if (this->currentMessageIndex == -1)
{
this->currentMessageIndex = 0;
DEBUG_MSG("First touch.\n");
e.frameChanged = true;
this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE;
}
else if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTION_SELECT)
{
sendText(
NODENUM_BROADCAST,
this->messages[this->currentMessageIndex],
true);
this->runState = CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE;
this->currentMessageIndex = -1;
this->notifyObservers(&e);
return 2000;
}
else if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTION_UP)
{
this->currentMessageIndex = getPrevIndex();
this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE;
DEBUG_MSG("MOVE UP\n");
}
else if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTION_DOWN)
{
this->currentMessageIndex = this->getNextIndex();
this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE;
DEBUG_MSG("MOVE DOWN\n");
}
if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE)
{
this->lastTouchMillis = millis();
this->notifyObservers(&e);
return INACTIVATE_AFTER_MS;
}
return 30000; // TODO: should return MAX_VAL
}
const char* CannedMessagePlugin::getCurrentMessage()
{
return this->messages[this->currentMessageIndex];
}
const char* CannedMessagePlugin::getPrevMessage()
{
return this->messages[this->getPrevIndex()];
}
const char* CannedMessagePlugin::getNextMessage()
{
return this->messages[this->getNextIndex()];
}
bool CannedMessagePlugin::shouldDraw()
{
if (!radioConfig.preferences.canned_message_plugin_enabled)
{
return false;
}
return (currentMessageIndex != -1) || (this->runState != CANNED_MESSAGE_RUN_STATE_INACTIVE);
}
int CannedMessagePlugin::getNextIndex()
{
if (this->currentMessageIndex >= (this->messagesCount -1))
{
return 0;
}
else
{
return this->currentMessageIndex + 1;
}
}
int CannedMessagePlugin::getPrevIndex()
{
if (this->currentMessageIndex <= 0)
{
return this->messagesCount - 1;
}
else
{
return this->currentMessageIndex - 1;
}
}
void CannedMessagePlugin::drawFrame(
OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
displayedNodeNum = 0; // Not currently showing a node pane
if (cannedMessagePlugin->runState == CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE)
{
display->setTextAlignment(TEXT_ALIGN_CENTER);
display->setFont(FONT_MEDIUM);
display->drawString(display->getWidth()/2 + x, 0 + y + 12, "Sending...");
}
else
{
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(FONT_SMALL);
display->drawString(0 + x, 0 + y, cannedMessagePlugin->getPrevMessage());
display->setFont(FONT_MEDIUM);
display->drawString(0 + x, 0 + y + 8, cannedMessagePlugin->getCurrentMessage());
display->setFont(FONT_SMALL);
display->drawString(0 + x, 0 + y + 24, cannedMessagePlugin->getNextMessage());
}
}

View File

@@ -0,0 +1,69 @@
#pragma once
#include "SinglePortPlugin.h"
#include "input/InputBroker.h"
enum cannedMessagePluginRunState
{
CANNED_MESSAGE_RUN_STATE_INACTIVE,
CANNED_MESSAGE_RUN_STATE_ACTIVE,
CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE,
CANNED_MESSAGE_RUN_STATE_ACTION_SELECT,
CANNED_MESSAGE_RUN_STATE_ACTION_UP,
CANNED_MESSAGE_RUN_STATE_ACTION_DOWN
};
#define CANNED_MESSAGE_PLUGIN_MESSAGE_MAX_COUNT 50
/**
* Due to config-packet size restrictions we cannot have user configuration bigger
* than Constants_DATA_PAYLOAD_LEN bytes.
*/
#define CANNED_MESSAGE_PLUGIN_MESSAGES_SIZE 200
class CannedMessagePlugin :
public SinglePortPlugin,
public Observable<const UIFrameEvent *>,
private concurrency::OSThread
{
CallbackObserver<CannedMessagePlugin, const InputEvent *> inputObserver =
CallbackObserver<CannedMessagePlugin, const InputEvent *>(
this, &CannedMessagePlugin::handleInputEvent);
public:
CannedMessagePlugin();
const char* getCurrentMessage();
const char* getPrevMessage();
const char* getNextMessage();
bool shouldDraw();
void eventUp();
void eventDown();
void eventSelect();
protected:
virtual int32_t runOnce() override;
void sendText(
NodeNum dest,
const char* message,
bool wantReplies);
int splitConfiguredMessages();
int getNextIndex();
int getPrevIndex();
int handleInputEvent(const InputEvent *event);
virtual bool wantUIFrame() override { return this->shouldDraw(); }
virtual Observable<const UIFrameEvent *>* getUIFrameObservable() override { return this; }
virtual void drawFrame(
OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) override;
int currentMessageIndex = -1;
cannedMessagePluginRunState runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
char messageStore[CANNED_MESSAGE_PLUGIN_MESSAGES_SIZE];
char *messages[CANNED_MESSAGE_PLUGIN_MESSAGE_MAX_COUNT];
int messagesCount = 0;
unsigned long lastTouchMillis = 0;
};
extern CannedMessagePlugin *cannedMessagePlugin;

View File

@@ -11,10 +11,14 @@
#include <OLEDDisplay.h> #include <OLEDDisplay.h>
#include <OLEDDisplayUi.h> #include <OLEDDisplayUi.h>
#include <OneWire.h> #include <OneWire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <Adafruit_BME680.h>
#define DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000 #define DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000
#define DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000 #define DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000
#define DS18B20_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000 #define DS18B20_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000
#define BME_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000
#define FAILED_STATE_SENSOR_READ_MULTIPLIER 10 #define FAILED_STATE_SENSOR_READ_MULTIPLIER 10
#define DISPLAY_RECEIVEID_MEASUREMENTS_ON_SCREEN true #define DISPLAY_RECEIVEID_MEASUREMENTS_ON_SCREEN true
@@ -36,8 +40,7 @@
int32_t EnvironmentalMeasurementPlugin::runOnce() int32_t EnvironmentalMeasurementPlugin::runOnce()
{ {
#ifndef NO_ESP32 // this only works on ESP32 devices #ifndef PORTDUINO
/* /*
Uncomment the preferences below if you want to use the plugin Uncomment the preferences below if you want to use the plugin
without having to configure it from the PythonAPI or WebUI. without having to configure it from the PythonAPI or WebUI.
@@ -50,11 +53,12 @@ int32_t EnvironmentalMeasurementPlugin::runOnce()
radioConfig.preferences.environmental_measurement_plugin_recovery_interval = 60; radioConfig.preferences.environmental_measurement_plugin_recovery_interval = 60;
radioConfig.preferences.environmental_measurement_plugin_display_farenheit = false; radioConfig.preferences.environmental_measurement_plugin_display_farenheit = false;
radioConfig.preferences.environmental_measurement_plugin_sensor_pin = 13; radioConfig.preferences.environmental_measurement_plugin_sensor_pin = 13;
radioConfig.preferences.environmental_measurement_plugin_sensor_type = radioConfig.preferences.environmental_measurement_plugin_sensor_type =
RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType:: RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType::
RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DS18B20; RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_BME280;
*/ */
if (!(radioConfig.preferences.environmental_measurement_plugin_measurement_enabled || if (!(radioConfig.preferences.environmental_measurement_plugin_measurement_enabled ||
radioConfig.preferences.environmental_measurement_plugin_screen_enabled)) { radioConfig.preferences.environmental_measurement_plugin_screen_enabled)) {
// If this plugin is not enabled, and the user doesn't want the display screen don't waste any OSThread time on it // If this plugin is not enabled, and the user doesn't want the display screen don't waste any OSThread time on it
@@ -70,11 +74,13 @@ int32_t EnvironmentalMeasurementPlugin::runOnce()
// it's possible to have this plugin enabled, only for displaying values on the screen. // it's possible to have this plugin enabled, only for displaying values on the screen.
// therefore, we should only enable the sensor loop if measurement is also enabled // therefore, we should only enable the sensor loop if measurement is also enabled
switch (radioConfig.preferences.environmental_measurement_plugin_sensor_type) { switch (radioConfig.preferences.environmental_measurement_plugin_sensor_type) {
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT11: case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT11:
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT12:
dht = new DHT(radioConfig.preferences.environmental_measurement_plugin_sensor_pin, DHT11); dht = new DHT(radioConfig.preferences.environmental_measurement_plugin_sensor_pin, DHT11);
this->dht->begin(); this->dht->begin();
this->dht->read(); this->dht->read();
DEBUG_MSG("EnvironmentalMeasurement: Opened DHT11 on pin: %d\n", DEBUG_MSG("EnvironmentalMeasurement: Opened DHT11/DHT12 on pin: %d\n",
radioConfig.preferences.environmental_measurement_plugin_sensor_pin); radioConfig.preferences.environmental_measurement_plugin_sensor_pin);
return (DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); return (DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS);
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DS18B20: case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DS18B20:
@@ -86,6 +92,42 @@ int32_t EnvironmentalMeasurementPlugin::runOnce()
DEBUG_MSG("EnvironmentalMeasurement: Opened DS18B20 on pin: %d\n", DEBUG_MSG("EnvironmentalMeasurement: Opened DS18B20 on pin: %d\n",
radioConfig.preferences.environmental_measurement_plugin_sensor_pin); radioConfig.preferences.environmental_measurement_plugin_sensor_pin);
return (DS18B20_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); return (DS18B20_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS);
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT21:
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT22:
dht = new DHT(radioConfig.preferences.environmental_measurement_plugin_sensor_pin, DHT22);
this->dht->begin();
this->dht->read();
DEBUG_MSG("EnvironmentalMeasurement: Opened DHT21/DHT22 on pin: %d\n",
radioConfig.preferences.environmental_measurement_plugin_sensor_pin);
return (DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS);
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_BME280:
unsigned bme280Status;
// Default i2c address for BME280
bme280Status = bme280.begin(0x76);
if (!bme280Status) {
DEBUG_MSG("Could not find a valid BME280 sensor, check wiring, address, sensor ID!");
// TODO more verbose diagnostics
} else {
DEBUG_MSG("EnvironmentalMeasurement: Opened BME280 on default i2c bus");
}
return (BME_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS);
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_BME680:
unsigned bme680Status;
// Default i2c address for BME280
bme680Status = bme680.begin(0x76);
if (!bme680Status) {
DEBUG_MSG("Could not find a valid BME680 sensor, check wiring, address, sensor ID!");
// TODO more verbose diagnostics
} else {
DEBUG_MSG("EnvironmentalMeasurement: Opened BME680 on default i2c bus");
// Set up oversampling and filter initialization
bme680.setTemperatureOversampling(BME680_OS_8X);
bme680.setHumidityOversampling(BME680_OS_2X);
bme680.setPressureOversampling(BME680_OS_4X);
bme680.setIIRFilterSize(BME680_FILTER_SIZE_3);
bme680.setGasHeater(320, 150); // 320*C for 150 ms
}
return (BME_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS);
default: default:
DEBUG_MSG("EnvironmentalMeasurement: Invalid sensor type selected; Disabling plugin"); DEBUG_MSG("EnvironmentalMeasurement: Invalid sensor type selected; Disabling plugin");
return (INT32_MAX); return (INT32_MAX);
@@ -129,9 +171,16 @@ int32_t EnvironmentalMeasurementPlugin::runOnce()
switch (radioConfig.preferences.environmental_measurement_plugin_sensor_type) { switch (radioConfig.preferences.environmental_measurement_plugin_sensor_type) {
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT11: case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT11:
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT12:
return (DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); return (DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS);
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DS18B20: case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DS18B20:
return (DS18B20_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); return (DS18B20_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS);
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT21:
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT22:
return (DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS);
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_BME280:
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_BME680:
return (BME_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS);
default: default:
return (DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); return (DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS);
} }
@@ -209,10 +258,10 @@ void EnvironmentalMeasurementPlugin::drawFrame(OLEDDisplay *display, OLEDDisplay
last_temp = String(CelsiusToFarenheit(lastMeasurement.temperature), 0) + "°F"; last_temp = String(CelsiusToFarenheit(lastMeasurement.temperature), 0) + "°F";
; ;
} }
display->drawString(x, y += fontHeight(FONT_MEDIUM) - 2, "From: " + lastSender + "(" + String(agoSecs) + "s)");
display->drawString(x, y += fontHeight(FONT_MEDIUM), display->drawString(x, y += fontHeight(FONT_SMALL) - 2,"Temp/Hum: " + last_temp + " / " + String(lastMeasurement.relative_humidity, 0) + "%");
lastSender + ": " + last_temp + "/" + String(lastMeasurement.relative_humidity, 0) + "%(" + if (lastMeasurement.barometric_pressure != 0)
String(agoSecs) + "s)"); display->drawString(x, y += fontHeight(FONT_SMALL),"Press: " + String(lastMeasurement.barometric_pressure, 0) + "hPA");
} }
bool EnvironmentalMeasurementPlugin::handleReceivedProtobuf(const MeshPacket &mp, EnvironmentalMeasurement *p) bool EnvironmentalMeasurementPlugin::handleReceivedProtobuf(const MeshPacket &mp, EnvironmentalMeasurement *p)
@@ -228,6 +277,7 @@ bool EnvironmentalMeasurementPlugin::handleReceivedProtobuf(const MeshPacket &mp
DEBUG_MSG("EnvironmentalMeasurement: Received data from %s\n", sender); DEBUG_MSG("EnvironmentalMeasurement: Received data from %s\n", sender);
DEBUG_MSG("EnvironmentalMeasurement->relative_humidity: %f\n", p->relative_humidity); DEBUG_MSG("EnvironmentalMeasurement->relative_humidity: %f\n", p->relative_humidity);
DEBUG_MSG("EnvironmentalMeasurement->temperature: %f\n", p->temperature); DEBUG_MSG("EnvironmentalMeasurement->temperature: %f\n", p->temperature);
DEBUG_MSG("EnvironmentalMeasurement->barometric_pressure: %f\n", p->barometric_pressure);
lastMeasurementPacket = packetPool.allocCopy(mp); lastMeasurementPacket = packetPool.allocCopy(mp);
@@ -245,6 +295,7 @@ bool EnvironmentalMeasurementPlugin::sendOurEnvironmentalMeasurement(NodeNum des
switch (radioConfig.preferences.environmental_measurement_plugin_sensor_type) { switch (radioConfig.preferences.environmental_measurement_plugin_sensor_type) {
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT11: case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT11:
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT12:
if (!this->dht->read(true)) { if (!this->dht->read(true)) {
sensor_read_error_count++; sensor_read_error_count++;
DEBUG_MSG("EnvironmentalMeasurement: FAILED TO READ DATA\n"); DEBUG_MSG("EnvironmentalMeasurement: FAILED TO READ DATA\n");
@@ -264,6 +315,26 @@ bool EnvironmentalMeasurementPlugin::sendOurEnvironmentalMeasurement(NodeNum des
DEBUG_MSG("EnvironmentalMeasurement: FAILED TO READ DATA\n"); DEBUG_MSG("EnvironmentalMeasurement: FAILED TO READ DATA\n");
return false; return false;
} }
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT21:
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT22:
if (!this->dht->read(true)) {
sensor_read_error_count++;
DEBUG_MSG("EnvironmentalMeasurement: FAILED TO READ DATA\n");
return false;
}
m.relative_humidity = this->dht->readHumidity();
m.temperature = this->dht->readTemperature();
break;
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_BME280:
m.temperature = bme280.readTemperature();
m.relative_humidity = bme280.readHumidity();
m.barometric_pressure = bme280.readPressure() / 100.0F;
break;
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_BME680:
m.temperature = bme680.readTemperature();
m.relative_humidity = bme680.readHumidity();
m.barometric_pressure = bme680.readPressure() / 100.0F;
break;
default: default:
DEBUG_MSG("EnvironmentalMeasurement: Invalid sensor type selected; Disabling plugin"); DEBUG_MSG("EnvironmentalMeasurement: Invalid sensor type selected; Disabling plugin");
return false; return false;
@@ -271,6 +342,7 @@ bool EnvironmentalMeasurementPlugin::sendOurEnvironmentalMeasurement(NodeNum des
DEBUG_MSG("EnvironmentalMeasurement->relative_humidity: %f\n", m.relative_humidity); DEBUG_MSG("EnvironmentalMeasurement->relative_humidity: %f\n", m.relative_humidity);
DEBUG_MSG("EnvironmentalMeasurement->temperature: %f\n", m.temperature); DEBUG_MSG("EnvironmentalMeasurement->temperature: %f\n", m.temperature);
DEBUG_MSG("EnvironmentalMeasurement->barometric_pressure: %f\n", m.barometric_pressure);
sensor_read_error_count = 0; sensor_read_error_count = 0;
@@ -278,6 +350,8 @@ bool EnvironmentalMeasurementPlugin::sendOurEnvironmentalMeasurement(NodeNum des
p->to = dest; p->to = dest;
p->decoded.want_response = wantReplies; p->decoded.want_response = wantReplies;
lastMeasurementPacket = packetPool.allocCopy(*p);
DEBUG_MSG("EnvironmentalMeasurement: Sending packet to mesh");
service.sendToMesh(p); service.sendToMesh(p);
return true; return true;
} }

View File

@@ -6,6 +6,9 @@
#include <OLEDDisplay.h> #include <OLEDDisplay.h>
#include <OLEDDisplayUi.h> #include <OLEDDisplayUi.h>
#include <OneWire.h> #include <OneWire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <Adafruit_BME680.h>
class EnvironmentalMeasurementPlugin : private concurrency::OSThread, public ProtobufPlugin<EnvironmentalMeasurement> class EnvironmentalMeasurementPlugin : private concurrency::OSThread, public ProtobufPlugin<EnvironmentalMeasurement>
{ {
@@ -16,15 +19,15 @@ class EnvironmentalMeasurementPlugin : private concurrency::OSThread, public Pro
{ {
lastMeasurementPacket = nullptr; lastMeasurementPacket = nullptr;
} }
virtual bool wantUIFrame(); virtual bool wantUIFrame() override;
virtual void drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y); virtual void drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) override;
protected: protected:
/** Called to handle a particular incoming message /** Called to handle a particular incoming message
@return true if you've guaranteed you've handled this message and no other handlers should be considered for it @return true if you've guaranteed you've handled this message and no other handlers should be considered for it
*/ */
virtual bool handleReceivedProtobuf(const MeshPacket &mp, EnvironmentalMeasurement *p); virtual bool handleReceivedProtobuf(const MeshPacket &mp, EnvironmentalMeasurement *p) override;
virtual int32_t runOnce(); virtual int32_t runOnce() override;
/** /**
* Send our EnvironmentalMeasurement into the mesh * Send our EnvironmentalMeasurement into the mesh
*/ */
@@ -33,9 +36,11 @@ class EnvironmentalMeasurementPlugin : private concurrency::OSThread, public Pro
private: private:
float CelsiusToFarenheit(float c); float CelsiusToFarenheit(float c);
bool firstTime = 1; bool firstTime = 1;
DHT *dht; DHT *dht = NULL;
OneWire *oneWire; OneWire *oneWire = NULL;
DS18B20 *ds18b20; DS18B20 *ds18b20 = NULL;
Adafruit_BME280 bme280;
Adafruit_BME680 bme680;
const MeshPacket *lastMeasurementPacket; const MeshPacket *lastMeasurementPacket;
uint32_t sensor_read_error_count = 0; uint32_t sensor_read_error_count = 0;
}; };

View File

@@ -156,13 +156,12 @@ ProcessMessage ExternalNotificationPlugin::handleReceived(const MeshPacket &mp)
if (radioConfig.preferences.ext_notification_plugin_enabled) { if (radioConfig.preferences.ext_notification_plugin_enabled) {
auto &p = mp.decoded;
if (getFrom(&mp) != nodeDB.getNodeNum()) { if (getFrom(&mp) != nodeDB.getNodeNum()) {
// TODO: This may be a problem if messages are sent in unicide, but I'm not sure if it will. // TODO: This may be a problem if messages are sent in unicide, but I'm not sure if it will.
// Need to know if and how this could be a problem. // Need to know if and how this could be a problem.
if (radioConfig.preferences.ext_notification_plugin_alert_bell) { if (radioConfig.preferences.ext_notification_plugin_alert_bell) {
auto &p = mp.decoded;
DEBUG_MSG("externalNotificationPlugin - Notification Bell\n"); DEBUG_MSG("externalNotificationPlugin - Notification Bell\n");
for (int i = 0; i < p.payload.size; i++) { for (int i = 0; i < p.payload.size; i++) {
if (p.payload.bytes[i] == ASCII_BELL) { if (p.payload.bytes[i] == ASCII_BELL) {

View File

@@ -26,7 +26,7 @@ class ExternalNotificationPlugin : public SinglePortPlugin, private concurrency:
@return ProcessMessage::STOP if you've guaranteed you've handled this message and no other handlers should be considered for it @return ProcessMessage::STOP if you've guaranteed you've handled this message and no other handlers should be considered for it
*/ */
virtual ProcessMessage handleReceived(const MeshPacket &mp); virtual ProcessMessage handleReceived(const MeshPacket &mp) override;
virtual int32_t runOnce(); virtual int32_t runOnce() override;
}; };

View File

@@ -26,14 +26,14 @@ class NodeInfoPlugin : public ProtobufPlugin<User>, private concurrency::OSThrea
@return true if you've guaranteed you've handled this message and no other handlers should be considered for it @return true if you've guaranteed you've handled this message and no other handlers should be considered for it
*/ */
virtual bool handleReceivedProtobuf(const MeshPacket &mp, User *p); virtual bool handleReceivedProtobuf(const MeshPacket &mp, User *p) override;
/** Messages can be received that have the want_response bit set. If set, this callback will be invoked /** Messages can be received that have the want_response bit set. If set, this callback will be invoked
* so that subclasses can (optionally) send a response back to the original sender. */ * so that subclasses can (optionally) send a response back to the original sender. */
virtual MeshPacket *allocReply(); virtual MeshPacket *allocReply() override;
/** Does our periodic broadcast */ /** Does our periodic broadcast */
virtual int32_t runOnce(); virtual int32_t runOnce() override;
}; };
extern NodeInfoPlugin *nodeInfoPlugin; extern NodeInfoPlugin *nodeInfoPlugin;

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