Compare commits

...

83 Commits

Author SHA1 Message Date
Thomas Göttgens
4fa8d02b08 update FromRadio UUID for nRF52 devices (#1795) 2022-10-13 09:32:54 -05:00
Thomas Göttgens
43fb0d80f1 Merge pull request #1794 from meshtastic/canned-spice
Display looks better that way...
2022-10-13 15:56:13 +02:00
Thomas Göttgens
b25ace14e5 Update CannedMessageModule.h 2022-10-13 15:44:27 +02:00
Thomas Göttgens
8734751bc4 make screen timeout work again 2022-10-13 15:31:57 +02:00
Thomas Göttgens
5559a1edb0 Display looks better that way... 2022-10-13 15:22:57 +02:00
Thomas Göttgens
bf503354f3 Merge pull request #1792 from meshtastic/atecca
Support for ATECCA608B Cryptographic Coprocessor
2022-10-13 14:34:44 +02:00
Thomas Göttgens
7b10441a28 update raspberry pi framework some more... 2022-10-13 14:21:48 +02:00
Thomas Göttgens
994e396c00 update Raspberry Pico Framework 2022-10-13 13:57:17 +02:00
Thomas Göttgens
6e22ee9061 make nRF52 happy 2022-10-13 13:31:19 +02:00
Thomas Göttgens
b5fb0f60b0 don't compile on Portduino 2022-10-13 13:01:24 +02:00
Thomas Göttgens
a7fe69ed6b Support for ATECCA608B Cryptographic Coprocessor 2022-10-13 12:55:28 +02:00
Thomas Göttgens
7f05298172 Merge pull request #1790 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-10-13 08:45:13 +02:00
thebentern
92a2505056 [create-pull-request] automated change 2022-10-12 23:42:47 +00:00
Ben Meadors
aae9d2fcf6 Package ota zip in final firmware bundle 2022-10-12 13:03:19 -05:00
Ben Meadors
b59e928589 Secure DFU mode for OTA updates with pin (#1789) 2022-10-12 10:31:39 -05:00
Ben Meadors
1db08b3b0e Add pico 2022-10-12 08:06:08 -05:00
Ben Meadors
2cf3c105a1 Add DFU package for nrf52 assets to build assets 2022-10-12 08:06:08 -05:00
Ben Meadors
505e4e8176 Run dfu begin first (#1786)
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
2022-10-12 07:55:17 -05:00
Thomas Göttgens
49a9973548 Merge pull request #1788 from meshtastic/bug-1787
fixes #1787
2022-10-12 13:26:21 +02:00
Thomas Göttgens
18af9d734d fixes #1787 2022-10-12 13:13:02 +02:00
Ben Meadors
3e22aafea8 Change UUID for FromRadio characteristic (#1785) 2022-10-11 20:01:26 -05:00
Ben Meadors
434db4347b Send device telemetry to phone every minute (#1784) 2022-10-11 10:21:30 -05:00
Thomas Göttgens
b2c3b405b1 Merge pull request #1783 from meshtastic/ota
debug print on early boot when OTA firmware is detected.
2022-10-10 23:40:19 +02:00
Thomas Göttgens
4bc8f6a6b9 Merge branch 'master' into ota 2022-10-10 23:14:26 +02:00
Thomas Göttgens
4534d17d79 debug print on early boot when OTA firmware is detected. 2022-10-10 23:05:24 +02:00
Ben Meadors
f88dde2f60 Send channels over phoneapi on want config (#1780)
* Send channels

* Doh!

* Adjust comments

* Missed a spot

* Consolidate

* Skipped disabled ones

* Fixed bounding

* Change order

* comment out disabled check for build artefact

* Remove loop

* Off by one

* Probably should start at zero

* Zero

* Oops

* enable dubug log

* Reset to index zero

Co-authored-by: Sacha Weatherstone <sachaw100@hotmail.com>
2022-10-10 10:36:49 -05:00
Thomas Göttgens
f8982ddaf8 Best Practise Platformio 6.x dependency definitions 2022-10-10 15:42:05 +02:00
Thomas Göttgens
784cd8c6f1 Merge pull request #1768 from meshtastic/nrf52-Rollup
Nrf52 rollup
2022-10-10 15:30:45 +02:00
Thomas Göttgens
c3ab8f12cf Merge branch 'master' into nrf52-Rollup 2022-10-10 15:09:49 +02:00
Thomas Göttgens
b5adb7babc Update nrf52840.ini 2022-10-10 15:09:31 +02:00
Thomas Göttgens
62c809a596 Merge pull request #1782 from meshtastic/lora-freq-check
Lora freq check
2022-10-10 12:53:14 +02:00
Thomas Göttgens
d2fe4426c1 Revert Platform Change for now. 2022-10-10 12:32:08 +02:00
Thomas Göttgens
984f0ca12c check allowed range for lora.channel_num 2022-10-10 12:28:31 +02:00
Thomas Göttgens
9d3eba9ea4 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-10-10 12:15:09 +02:00
Thomas Göttgens
323f81eaba Merge branch 'master' into nrf52-Rollup 2022-10-10 12:06:44 +02:00
Thomas Göttgens
8d0e25fd82 Merge pull request #1770 from meshtastic/ota
Switch to OTA firmware
2022-10-09 11:54:16 +02:00
Thomas Göttgens
20eaddee58 - fix conditional include for nRF52 (no OTA there)
- fix compiler warning in Canned Messages
2022-10-09 11:35:19 +02:00
Thomas Göttgens
30b1bd85d9 fix build for non-esp32 2022-10-09 11:19:33 +02:00
Thomas Göttgens
09cce094d1 Merge branch 'master' into ota 2022-10-09 11:00:20 +02:00
Thomas Göttgens
33a208e3c4 Merge pull request #1777 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-10-09 11:00:01 +02:00
caveman99
dd4c4fba80 [create-pull-request] automated change 2022-10-09 08:55:33 +00:00
Sacha Weatherstone
a17c40ad09 Merge branch 'master' into ota 2022-10-09 16:44:24 +10:00
Sacha Weatherstone
9d73e606ac Merge pull request #1774 from meshtastic/node-db
erase oldest entry from NodeDB if it is full
2022-10-09 16:40:46 +10:00
Ben Meadors
da12360105 Merge branch 'master' into node-db 2022-10-08 13:48:35 -05:00
GUVWAF
ee1ae627a3 Model the time it is busy receiving/transmitting (#1776)
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
2022-10-08 12:10:50 -05:00
Thomas Göttgens
137a8dcfdf Merge pull request #1775 from meshtastic/i2cscan-fix
move and repeat i2c scan to fix BLE PIN
2022-10-08 17:52:32 +02:00
Thomas Göttgens
b2d753ed86 move and repeat i2c scan to fix BLE PIN 2022-10-08 17:36:39 +02:00
Thomas Göttgens
6e40102f26 - use bigger screen fonts on Wiphone
- erase oldest entry from NodeDB if it is full.
2022-10-08 17:07:16 +02:00
Ben Meadors
511fe23b8a Merge branch 'master' into ota 2022-10-08 08:22:16 -05:00
Thomas Göttgens
e433895873 Merge pull request #1773 from meshtastic/canned-messages
Fix another crash in Canned Messages
2022-10-08 15:09:58 +02:00
Thomas Göttgens
5572195af9 Fix another crash in Canned Messages 2022-10-08 14:52:21 +02:00
Thomas Göttgens
cb956cd35b Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-10-08 14:35:07 +02:00
Ben Meadors
b551c7738e Merge branch 'master' into ota 2022-10-08 07:28:35 -05:00
GUVWAF
3d45c4dbd8 Don't resend ACK if another module sent a response (#1772)
* strcmp returns zero if strings are equal

* Make debug message more clear

* Don't resend ACK if another module sent a response

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
2022-10-08 07:27:59 -05:00
Thomas Göttgens
8681489cb7 Merge pull request #1771 from meshtastic/compass-size
Scale Compass circle to bigger screens
2022-10-08 13:22:14 +02:00
Thomas Göttgens
ed328766b2 Scale Compass circle to bigger screens 2022-10-08 12:32:48 +02:00
Thomas Göttgens
fb852ee6eb Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-10-08 11:25:46 +02:00
Thomas Göttgens
a6ee708b90 Merge branch 'master' into ota 2022-10-08 11:21:33 +02:00
Thomas Göttgens
c9398e7b8a - prevent crash when no messages defined
- remove debug print
2022-10-08 11:20:54 +02:00
Thomas Göttgens
b591e35442 Switch to OTA firmware 2022-10-08 11:10:29 +02:00
Thomas Göttgens
e50e15dc04 Merge pull request #1769 from meshtastic/RTC
1.0.1 RTC LIB is released on PIO Registry
2022-10-08 11:09:54 +02:00
Thomas Göttgens
d4e65d8607 1.0.1 RTC LIB is released on PIO Registry 2022-10-08 11:09:16 +02:00
Thomas Göttgens
63ced7da7c use upstream nRF52 toolkit. (TEST)
also RTC Lib 1.0.1 is finally out.
2022-10-07 20:28:20 +02:00
Thomas Göttgens
03868d05db Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-10-07 20:23:00 +02:00
Thomas Göttgens
186374525a Don't mix MQTT Payloads of Firmware 1.2 and 1.3/2.0 (#1767) 2022-10-07 12:54:42 -05:00
Thomas Göttgens
f116585c2a Don't mix MQTT Payloads of Firmware 1.2 and 1.3/2.0 2022-10-07 19:26:45 +02:00
Thomas Göttgens
f4945729bc Merge pull request #1766 from meshtastic/new-sounds
use F# as startup and shutdown sound triple
2022-10-07 19:16:50 +02:00
Thomas Göttgens
a3c76232c8 use F# as startup and shutdown sound triple. The existing tuuut-tut-tut was getting on my nerves 2022-10-07 19:03:49 +02:00
Thomas Göttgens
5bc41118e2 Merge pull request #1760 from meshtastic/support-rak14004
Use small font for freetext messages
2022-10-07 18:58:28 +02:00
Thomas Göttgens
9445a96b3a Merge branch 'support-rak14004' of github.com:meshtastic/Meshtastic-device 2022-10-07 18:40:51 +02:00
Thomas Göttgens
a5761069ca Finalize destination selection. Primary Channel only for now. 2022-10-07 18:40:15 +02:00
Thomas Göttgens
2d4bfe183c Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-10-07 16:42:29 +02:00
Ben Meadors
bf4115a80f Telemetry sensors re-map (#1765)
* Add factory erase uf2 to the release assets

* Sensors map

* Uncomment sensors
2022-10-07 08:33:07 -05:00
Ben Meadors
b2e84dfd29 Merge branch 'master' into support-rak14004 2022-10-07 06:58:08 -05:00
lewis he
004f6fa4d6 Add t-beam-s3-core onboard device support. (#1764)
* Change t-beam-s3-core pins definitions

* Add t-beam-s3-core power initialization to properly initialize the I2C device

* Add 6-axis and 3-axis sensor detection
2022-10-07 06:57:55 -05:00
Thomas Göttgens
cefd4cd647 Merge pull request #1762 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-10-06 23:15:59 +02:00
thebentern
fd2ae61e3e [create-pull-request] automated change 2022-10-06 20:53:47 +00:00
Thomas Göttgens
7cda61ca01 - preliminary work for node selection
- show sending screen on immediate click
2022-10-06 22:34:55 +02:00
Thomas Göttgens
98e1d52eaa Merge branch 'support-rak14004' of github.com:meshtastic/Meshtastic-device 2022-10-06 18:41:33 +02:00
Thomas Göttgens
1d09beb8a7 word wrap long input and fix compiler warnings 2022-10-06 18:40:31 +02:00
Thomas Göttgens
d44cce2928 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-10-06 17:24:48 +02:00
Thomas Göttgens
51b3d4d06e Merge branch 'master' into support-rak14004 2022-10-06 17:24:33 +02:00
Thomas Göttgens
a17ddaa951 Use small font for freetext messages 2022-10-06 17:24:08 +02:00
54 changed files with 663 additions and 210 deletions

View File

@@ -224,6 +224,7 @@ jobs:
path: |
release/*.uf2
release/*.elf
release/*.zip
retention-days: 90
build-rpi2040:
@@ -368,7 +369,7 @@ jobs:
id: version
- name: Move files up
run: mv -b -t ./ ./*tbeam-1*/littlefs*.bin ./*tbeam-1*/bleota.bin ./**/firmware*.bin ./*t-echo*/Meshtastic_nRF52_factory_erase.uf2 ./**/firmware-*.uf2 ./**/*.elf ./**/meshtasticd_linux_amd64 ./*native*/*device-*.sh ./*native*/*device-*.bat
run: mv -b -t ./ ./*tbeam-1*/littlefs*.bin ./*tbeam-1*/bleota.bin ./**/firmware*.bin ./*t-echo*/Meshtastic_nRF52_factory_erase.uf2 ./**/firmware-*.uf2 ./**/firmware-*-ota.zip ./**/*.elf ./**/meshtasticd_linux_amd64 ./*native*/*device-*.sh ./*native*/*device-*.bat
- name: Repackage in single firmware zip
uses: actions/upload-artifact@v2
@@ -377,6 +378,7 @@ jobs:
path: |
./*.bin
./*.uf2
./firmware-*-ota.zip
./meshtasticd_linux_amd64
./device-*.sh
./device-*.bat

View File

@@ -1,7 +1,7 @@
; Common settings for ESP targes, mixin with extends = esp32_base
[esp32_base]
extends = arduino_base
platform = espressif32@^5.2.0
platform = platformio/espressif32@^5.2.0
build_src_filter =
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2040>
upload_speed = 921600

View File

@@ -1,6 +1,6 @@
[esp32s3_base]
extends = arduino_base
platform = espressif32@^5.2.0
platform = platformio/espressif32@^5.2.0
build_src_filter =
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2040>
upload_speed = 961200

View File

@@ -1,11 +1,9 @@
[nrf52_base]
; Instead of the standard nordicnrf52 platform, we use our fork which has our added variant files
; platform = nordicnrf52 ;pending https://github.com/platformio/builder-framework-arduino-nrf5/pull/7
platform = https://github.com/meshtastic/platform-nordicnrf52.git#merge
platform = platformio/nordicnrf52@^9.4.0
extends = arduino_base
build_type = debug ; I'm debugging with ICE a lot now
; note: liboberon provides the AES256 implementation for NRF52 (though not using the hardware acceleration of the NRF52840 - FIXME)
build_flags =
${arduino_base.build_flags} -Wno-unused-variable
-Isrc/platform/nrf52

View File

@@ -4,7 +4,7 @@ build_flags = ${nrf52_base.build_flags}
lib_deps =
${arduino_base.lib_deps}
${environmental_base.lib_deps}
https://github.com/Kongduino/Adafruit_nRFCrypto.git#20fc7fdaf086bd70e901c007dd23c6e8856aec25
https://github.com/Kongduino/Adafruit_nRFCrypto.git#e31a8825ea3300b163a0a3c1ddd5de34e10e1371
; Note: By default no lora device is created for this build - it uses a simulated interface
[env:nrf52840dk]

View File

@@ -1,6 +1,6 @@
; Common settings for rp2040 Processor based targets
[rp2040_base]
platform = https://github.com/maxgerhardt/platform-raspberrypi.git
platform = https://github.com/maxgerhardt/platform-raspberrypi.git#5ce1a228e7cae453f366deb8962252b9b7356bbc
extends = arduino_base
board_build.core = earlephilhower
board_build.filesystem_size = 0.5m

View File

@@ -1,5 +1,5 @@
[stm32wl5e_base]
platform = ststm32
platform = platformio/ststm32@^15.4.1
board = generic_wl5e
framework = arduino
build_type = debug

View File

@@ -26,7 +26,9 @@ basename=firmware-$1-$VERSION
pio run --environment $1 # -v
SRCELF=.pio/build/$1/firmware.elf
DFUPKG=.pio/build/$1/firmware.zip
cp $SRCELF $OUTDIR/$basename.elf
cp $DFUPKG $OUTDIR/$basename-ota.zip
echo "Generating NRF52 uf2 file"
SRCHEX=.pio/build/$1/firmware.hex

View File

@@ -2,7 +2,8 @@
; https://docs.platformio.org/page/projectconf.html
[platformio]
default_envs = tbeam
;default_envs = tbeam
;default_envs = pico
;default_envs = tbeam-s3-core
;default_envs = tbeam0.7
;default_envs = heltec-v1
@@ -64,6 +65,7 @@ lib_deps =
${env.lib_deps}
; Portduino is using meshtastic fork for now
jgromes/RadioLib@5.4.1
https://github.com/caveman99/SparkFun_ATECCX08a_Arduino_Library.git#008e7f9d40bad66b2f7a0074aaac05b7c424339d
build_flags = ${env.build_flags} -Os
-DRADIOLIB_SPI_PARANOID=0

View File

@@ -7,7 +7,7 @@ const uint8_t MESH_SERVICE_UUID_16[16u] = {0xfd, 0xea, 0x73, 0xe2, 0xca, 0x5d, 0
0x1f, 0x46, 0xa8, 0x15, 0x18, 0xb2, 0xa1, 0x6b};
const uint8_t TORADIO_UUID_16[16u] = {0xe7, 0x01, 0x44, 0x12, 0x66, 0x78, 0xdd, 0xa1,
0xad, 0x4d, 0x9e, 0x12, 0xd2, 0x76, 0x5c, 0xf7};
const uint8_t FROMRADIO_UUID_16[16u] = {0xd5, 0x54, 0xe4, 0xc5, 0x25, 0xc5, 0x31, 0xa5,
0x55, 0x4a, 0x02, 0xee, 0xc2, 0xbc, 0xa2, 0x8b};
const uint8_t FROMRADIO_UUID_16[16u] = {0x02, 0x00, 0x12, 0xac, 0x42, 0x02, 0x78, 0xb8,
0xed, 0x11, 0x93, 0x49, 0x9e, 0xe6, 0x55, 0x2c};
const uint8_t FROMNUM_UUID_16[16u] = {0x53, 0x44, 0xe3, 0x47, 0x75, 0xaa, 0x70, 0xa6,
0x66, 0x4f, 0x00, 0xa8, 0x8c, 0xa1, 0x9d, 0xed};

View File

@@ -9,7 +9,7 @@
#define MESH_SERVICE_UUID "6ba1b218-15a8-461f-9fa8-5dcae273eafd"
#define TORADIO_UUID "f75c76d2-129e-4dad-a1dd-7866124401e7"
#define FROMRADIO_UUID "8ba2bcc2-ee02-4a55-a531-c525c5e454d5"
#define FROMRADIO_UUID "2c55e69e-4993-11ed-b878-0242ac120002"
#define FROMNUM_UUID "ed9da18c-a800-4f66-a670-aa7547e34453"
// NRF52 wants these constants as byte arrays

View File

@@ -368,8 +368,21 @@ bool Power::axpChipInit()
#ifdef HAS_PMU
TwoWire * w = NULL;
// Use macro to distinguish which wire is used by PMU
#ifdef PMU_USE_WIRE1
w = &Wire1;
#else
w = &Wire;
#endif
/**
* It is not necessary to specify the wire pin,
* just input the wire, because the wire has been initialized in main.cpp
*/
if (!PMU) {
PMU = new XPowersAXP2101(Wire, I2C_SDA, I2C_SCL);
PMU = new XPowersAXP2101(*w);
if (!PMU->init()) {
DEBUG_MSG("Warning: Failed to find AXP2101 power management\n");
delete PMU;
@@ -380,7 +393,7 @@ bool Power::axpChipInit()
}
if (!PMU) {
PMU = new XPowersAXP192(Wire, I2C_SDA, I2C_SCL);
PMU = new XPowersAXP192(*w);
if (!PMU->init()) {
DEBUG_MSG("Warning: Failed to find AXP192 power management\n");
delete PMU;
@@ -396,7 +409,9 @@ bool Power::axpChipInit()
* In order not to affect other devices, if the initialization of the PMU fails, Wire needs to be re-initialized once,
* if there are multiple devices sharing the bus.
* * */
Wire.begin(I2C_SDA, I2C_SCL);
#ifndef PMU_USE_WIRE1
w->begin(I2C_SDA, I2C_SCL);
#endif
return false;
}
@@ -456,6 +471,23 @@ bool Power::axpChipInit()
PMU->setPowerChannelVoltage(XPOWERS_DCDC3, 3300);
PMU->enablePowerOutput(XPOWERS_DCDC3);
/**
* ALDO2 cannot be turned off.
* It is a necessary condition for sensor communication.
* It must be turned on to properly access the sensor and screen
* It is also responsible for the power supply of PCF8563
*/
PMU->setPowerChannelVoltage(XPOWERS_ALDO2, 3300);
PMU->enablePowerOutput(XPOWERS_ALDO2);
// 6-axis , magnetometer ,bme280 , oled screen power channel
PMU->setPowerChannelVoltage(XPOWERS_ALDO1, 3300);
PMU->enablePowerOutput(XPOWERS_ALDO1);
// sdcard power channle
PMU->setPowerChannelVoltage(XPOWERS_BLDO1, 3300);
PMU->enablePowerOutput(XPOWERS_BLDO1);
// PMU->setPowerChannelVoltage(XPOWERS_DCDC4, 3300);
// PMU->enablePowerOutput(XPOWERS_DCDC4);

View File

@@ -36,6 +36,7 @@ struct ToneDuration {
#define NOTE_A3 220
#define NOTE_AS3 233
#define NOTE_B3 247
#define NOTE_CS4 277
const int DURATION_1_8 = 125; // 1/8 note
const int DURATION_1_4 = 250; // 1/4 note
@@ -65,16 +66,17 @@ void playBeep() { tone(PIN_BUZZER, NOTE_B3, DURATION_1_4); }
#endif
void playStartMelody() {
ToneDuration melody[] = {{NOTE_B3, DURATION_1_4},
{NOTE_B3, DURATION_1_8},
{NOTE_B3, DURATION_1_8}};
ToneDuration melody[] = {{NOTE_FS3, DURATION_1_8},
{NOTE_AS3, DURATION_1_8},
{NOTE_CS4, DURATION_1_4}};
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
}
void playShutdownMelody() {
ToneDuration melody[] = {{NOTE_B3, DURATION_1_4},
{NOTE_G3, DURATION_1_8},
{NOTE_D3, DURATION_1_8}};
ToneDuration melody[] = {{NOTE_CS4, DURATION_1_8},
{NOTE_AS3, DURATION_1_8},
{NOTE_FS3, DURATION_1_4}};
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
}
#endif

View File

@@ -108,6 +108,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define MCP9808_ADDR 0x18
#define INA_ADDR 0x40
#define INA_ADDR_ALTERNATE 0x41
#define QMC6310_ADDR 0x1C
#define QMI8658_ADDR 0x6B
// -----------------------------------------------------------------------------
// Security
// -----------------------------------------------------------------------------
#define ATECC608B_ADDR 0x35
// -----------------------------------------------------------------------------
// GPS

View File

@@ -9,6 +9,41 @@
#endif
#if HAS_WIRE
void printATECCInfo()
{
#ifndef ARCH_PORTDUINO
atecc.readConfigZone(false);
DEBUG_MSG("ATECC608B Serial Number: ");
for (int i = 0 ; i < 9 ; i++) {
DEBUG_MSG("%02x",atecc.serialNumber[i]);
}
DEBUG_MSG(", Rev Number: ");
for (int i = 0 ; i < 4 ; i++) {
DEBUG_MSG("%02x",atecc.revisionNumber[i]);
}
DEBUG_MSG("\n");
DEBUG_MSG("ATECC608B Config %s",atecc.configLockStatus ? "Locked" : "Unlocked");
DEBUG_MSG(", Data %s",atecc.dataOTPLockStatus ? "Locked" : "Unlocked");
DEBUG_MSG(", Slot 0 %s\n",atecc.slot0LockStatus ? "Locked" : "Unlocked");
if (atecc.configLockStatus && atecc.dataOTPLockStatus && atecc.slot0LockStatus) {
if (atecc.generatePublicKey() == false) {
DEBUG_MSG("ATECC608B Error generating public key\n");
} else {
DEBUG_MSG("ATECC608B Public Key: ");
for (int i = 0 ; i < 64 ; i++) {
DEBUG_MSG("%02x",atecc.publicKey64Bytes[i]);
}
DEBUG_MSG("\n");
}
}
#endif
}
uint16_t getRegisterValue(uint8_t address, uint8_t reg, uint8_t length) {
uint16_t value = 0x00;
Wire.beginTransmission(address);
@@ -79,6 +114,17 @@ void scanI2Cdevice(void)
DEBUG_MSG("unknown display found\n");
}
}
#ifndef ARCH_PORTDUINO
if (addr == ATECC608B_ADDR){
keystore_found = addr;
if (atecc.begin(keystore_found) == true) {
DEBUG_MSG("ATECC608B initialized\n");
} else {
DEBUG_MSG("ATECC608B initialization failed\n");
}
printATECCInfo();
}
#endif
#ifdef RV3028_RTC
if (addr == RV3028_RTC){
rtc_found = addr;
@@ -145,6 +191,14 @@ void scanI2Cdevice(void)
nodeTelemetrySensorsMap[TelemetrySensorType_MCP9808] = addr;
DEBUG_MSG("MCP9808 sensor found at address 0x%x\n", (uint8_t)addr);
}
if(addr == QMC6310_ADDR){
DEBUG_MSG("QMC6310 3-Axis magnetic sensor found at address 0x%x\n", (uint8_t)addr);
nodeTelemetrySensorsMap[TelemetrySensorType_QMC6310] = addr;
}
if(addr == QMI8658_ADDR){
DEBUG_MSG("QMI8658 6-Axis inertial measurement sensor found at address 0x%x\n", (uint8_t)addr);
nodeTelemetrySensorsMap[TelemetrySensorType_QMI8658] = addr;
}
} else if (err == 4) {
DEBUG_MSG("Unknow error at address 0x%x\n", addr);
}

View File

@@ -57,7 +57,6 @@ namespace graphics
// This means the *visible* area (sh1106 can address 132, but shows 128 for example)
#define IDLE_FRAMERATE 1 // in fps
#define COMPASS_DIAM 44
// DEBUG
#define NUM_EXTRA_FRAMES 3 // text message and debug frame
@@ -98,7 +97,7 @@ static uint16_t displayWidth, displayHeight;
#define SCREEN_WIDTH displayWidth
#define SCREEN_HEIGHT displayHeight
#if defined(USE_EINK) || defined(ILI9341_DRIVER)
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS)
// The screen is bigger so use bigger fonts
#define FONT_SMALL ArialMT_Plain_16
#define FONT_MEDIUM ArialMT_Plain_24
@@ -669,6 +668,26 @@ static bool hasPosition(NodeInfo *n)
return n->has_position && (n->position.latitude_i != 0 || n->position.longitude_i != 0);
}
static uint16_t getCompassDiam(OLEDDisplay *display)
{
uint16_t diam = 0;
// get the smaller of the 2 dimensions and subtract 20
if(display->getWidth() > display->getHeight()) {
diam = display->getHeight();
// if 2/3 of the other size would be smaller, use that
if (diam > (display->getWidth() * 2 / 3)) {
diam = display->getWidth() * 2 / 3;
}
} else {
diam = display->getWidth();
if (diam > (display->getHeight() * 2 / 3)) {
diam = display->getHeight() * 2 / 3;
}
}
return diam - 20;
};
/// We will skip one node - the one for us, so we just blindly loop over all
/// nodes
static size_t nodeIndex;
@@ -685,7 +704,7 @@ static void drawNodeHeading(OLEDDisplay *display, int16_t compassX, int16_t comp
for (int i = 0; i < 4; i++) {
arrowPoints[i]->rotate(headingRadian);
arrowPoints[i]->scale(COMPASS_DIAM * 0.6);
arrowPoints[i]->scale(getCompassDiam(display) * 0.6);
arrowPoints[i]->translate(compassX, compassY);
}
drawLine(display, tip, tail);
@@ -707,7 +726,7 @@ static void drawCompassNorth(OLEDDisplay *display, int16_t compassX, int16_t com
for (int i = 0; i < 4; i++) {
// North on compass will be negative of heading
rosePoints[i]->rotate(-myHeading);
rosePoints[i]->scale(COMPASS_DIAM);
rosePoints[i]->scale(getCompassDiam(display));
rosePoints[i]->translate(compassX, compassY);
}
drawLine(display, N1, N3);
@@ -772,7 +791,7 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
const char *fields[] = {username, distStr, signalStr, lastStr, NULL};
// coordinates for the center of the compass/circle
int16_t compassX = x + SCREEN_WIDTH - COMPASS_DIAM / 2 - 5, compassY = y + SCREEN_HEIGHT / 2;
int16_t compassX = x + SCREEN_WIDTH - getCompassDiam(display) / 2 - 5, compassY = y + SCREEN_HEIGHT / 2;
bool hasNodeHeading = false;
if (ourNode && hasPosition(ourNode)) {
@@ -813,7 +832,7 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
// Debug info for gps lock errors
// DEBUG_MSG("ourNode %d, ourPos %d, theirPos %d\n", !!ourNode, ourNode && hasPosition(ourNode), hasPosition(node));
display->drawString(compassX - FONT_HEIGHT_SMALL / 4, compassY - FONT_HEIGHT_SMALL / 2, "?");
display->drawCircle(compassX, compassY, COMPASS_DIAM / 2);
display->drawCircle(compassX, compassY, getCompassDiam(display) / 2);
// Must be after distStr is populated
drawColumns(display, x, y, fields);

View File

@@ -17,7 +17,7 @@ uint8_t read_from_14004(uint8_t reg, uint8_t *data, uint8_t length)
Wire.write(reg);
Wire.endTransmission(); // stop transmitting
delay(20);
Wire.requestFrom(CARDKB_ADDR, length);
Wire.requestFrom(CARDKB_ADDR, (int)length);
int i = 0;
while ( Wire.available() ) // slave may send less than requested
{

View File

@@ -80,6 +80,12 @@ uint8_t kb_model;
// The I2C address of the RTC Module (if found)
uint8_t rtc_found;
// Keystore Chips
uint8_t keystore_found;
#ifndef ARCH_PORTDUINO
ATECCX08A atecc;
#endif
bool eink_found = true;
uint32_t serialSinceMsec;
@@ -87,7 +93,7 @@ uint32_t serialSinceMsec;
bool pmu_found;
// Array map of sensor types (as array index) and i2c address as value we'll find in the i2c scan
uint8_t nodeTelemetrySensorsMap[TelemetrySensorType_LPS22+1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
uint8_t nodeTelemetrySensorsMap[TelemetrySensorType_QMI8658+1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
Router *router = NULL; // Users of router don't care what sort of subclass implements that API
@@ -214,6 +220,10 @@ void setup()
// router = new DSRRouter();
router = new ReliableRouter();
#ifdef I2C_SDA1
Wire1.begin(I2C_SDA1, I2C_SCL1);
#endif
#ifdef I2C_SDA
Wire.begin(I2C_SDA, I2C_SCL);
#elif HAS_WIRE
@@ -229,6 +239,7 @@ void setup()
delay(1);
#endif
// We need to scan here to decide if we have a screen for nodeDB.init()
scanI2Cdevice();
#ifdef RAK4630
// scanEInkDevice();
@@ -269,6 +280,14 @@ void setup()
powerStatus->observe(&power->newStatus);
power->setup(); // Must be after status handler is installed, so that handler gets notified of the initial configuration
/*
* Repeat the scanning for I2C devices after power initialization.
* Boards with an PMU need to be powered on to correctly scan to the device address, such as t-beam-s3-core
*/
if ((HW_VENDOR == HardwareModel_LILYGO_TBEAM_S3_CORE) || (HW_VENDOR == HardwareModel_TBEAM)) {
scanI2Cdevice();
}
// Init our SPI controller (must be before screen and lora)
initSPI();
#ifndef ARCH_ESP32

View File

@@ -6,19 +6,27 @@
#include "PowerStatus.h"
#include "graphics/Screen.h"
#include "mesh/generated/telemetry.pb.h"
#ifndef ARCH_PORTDUINO
#include <SparkFun_ATECCX08a_Arduino_Library.h>
#endif
extern uint8_t screen_found;
extern uint8_t screen_model;
extern uint8_t cardkb_found;
extern uint8_t kb_model;
extern uint8_t rtc_found;
extern uint8_t keystore_found;
extern bool eink_found;
extern bool pmu_found;
extern bool isCharging;
extern bool isUSBPowered;
extern uint8_t nodeTelemetrySensorsMap[TelemetrySensorType_LPS22+1];
#ifndef ARCH_PORTDUINO
extern ATECCX08A atecc;
#endif
extern uint8_t nodeTelemetrySensorsMap[TelemetrySensorType_QMI8658+1];
extern int TCPPort; // set by Portduino

View File

@@ -112,7 +112,7 @@ void MeshModule::callPlugins(const MeshPacket &mp, RxSource src)
bool rxChannelOk = !pi.boundChannel || (mp.from == 0) ||
!ch ||
strlen(ch->settings.name) > 0 ||
(strcmp(ch->settings.name, pi.boundChannel) == 0);
(strcasecmp(ch->settings.name, pi.boundChannel) == 0);
if (!rxChannelOk) {
// no one should have already replied!

View File

@@ -699,11 +699,23 @@ NodeInfo *NodeDB::getOrCreateNode(NodeNum n)
if (!info) {
if (*numNodes >= MAX_NUM_NODES) {
screen->print("error: node_db full!\n");
DEBUG_MSG("ERROR! could not create new node, node_db is full! (%d nodes)", *numNodes);
return NULL;
screen->print("warning: node_db full! erasing oldest entry\n");
// look for oldest node and erase it
uint32_t oldest = UINT32_MAX;
int oldestIndex = -1;
for (int i = 0; i < *numNodes; i++) {
if (nodes[i].last_heard < oldest) {
oldest = nodes[i].last_heard;
oldestIndex = i;
}
}
// Shove the remaining nodes down the chain
for (int i = oldestIndex; i < *numNodes - 1; i++) {
nodes[i] = nodes[i + 1];
}
(*numNodes)--;
}
// add the node
// add the node at the end
info = &nodes[(*numNodes)++];
// everything is missing except the nodenum

View File

@@ -79,17 +79,17 @@ bool PhoneAPI::handleToRadio(const uint8_t *buf, size_t bufLength)
memset(&toRadioScratch, 0, sizeof(toRadioScratch));
if (pb_decode_from_bytes(buf, bufLength, ToRadio_fields, &toRadioScratch)) {
switch (toRadioScratch.which_payload_variant) {
case ToRadio_packet_tag:
return handleToRadioPacket(toRadioScratch.packet);
case ToRadio_want_config_id_tag:
config_nonce = toRadioScratch.want_config_id;
DEBUG_MSG("Client wants config, nonce=%u\n", config_nonce);
handleStartConfig();
break;
case ToRadio_disconnect_tag:
DEBUG_MSG("Disconnecting from phone\n");
close();
break;
case ToRadio_packet_tag:
return handleToRadioPacket(toRadioScratch.packet);
case ToRadio_want_config_id_tag:
config_nonce = toRadioScratch.want_config_id;
DEBUG_MSG("Client wants config, nonce=%u\n", config_nonce);
handleStartConfig();
break;
case ToRadio_disconnect_tag:
DEBUG_MSG("Disconnecting from phone\n");
close();
break;
default:
// Ignore nop messages
// DEBUG_MSG("Error: unexpected ToRadio variant\n");
@@ -109,8 +109,10 @@ bool PhoneAPI::handleToRadio(const uint8_t *buf, size_t bufLength)
*
* Our sending states progress in the following sequence (the client app ASSUMES THIS SEQUENCE, DO NOT CHANGE IT):
* STATE_SEND_MY_INFO, // send our my info record
* STATE_SEND_CHANNELS
* STATE_SEND_NODEINFO, // states progress in this order as the device sends to the client
STATE_SEND_CONFIG,
STATE_SEND_MODULE_CONFIG,
STATE_SEND_COMPLETE_ID,
STATE_SEND_PACKETS // send packets or debug strings
*/
@@ -128,7 +130,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
case STATE_SEND_NOTHING:
DEBUG_MSG("getFromRadio=STATE_SEND_NOTHING\n");
break;
case STATE_SEND_MY_INFO:
DEBUG_MSG("getFromRadio=STATE_SEND_MY_INFO\n");
// If the user has specified they don't want our node to share its location, make sure to tell the phone
@@ -154,51 +156,63 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
// Stay in current state until done sending nodeinfos
} else {
DEBUG_MSG("Done sending nodeinfos\n");
state = STATE_SEND_CONFIG;
state = STATE_SEND_CHANNELS;
// Go ahead and send that ID right now
return getFromRadio(buf);
}
break;
}
case STATE_SEND_CHANNELS:
DEBUG_MSG("getFromRadio=STATE_SEND_CHANNELS\n");
fromRadioScratch.which_payload_variant = FromRadio_channel_tag;
fromRadioScratch.channel = channels.getByIndex(config_state);
config_state++;
// Advance when we have sent all of our Channels
if (config_state >= MAX_NUM_CHANNELS) {
state = STATE_SEND_CONFIG;
config_state = Config_device_tag;
}
break;
case STATE_SEND_CONFIG:
DEBUG_MSG("getFromRadio=STATE_SEND_CONFIG\n");
fromRadioScratch.which_payload_variant = FromRadio_config_tag;
switch (config_state) {
case Config_device_tag:
fromRadioScratch.config.which_payload_variant = Config_device_tag;
fromRadioScratch.config.payload_variant.device = config.device;
break;
case Config_position_tag:
fromRadioScratch.config.which_payload_variant = Config_position_tag;
fromRadioScratch.config.payload_variant.position = config.position;
break;
case Config_power_tag:
fromRadioScratch.config.which_payload_variant = Config_power_tag;
fromRadioScratch.config.payload_variant.power = config.power;
fromRadioScratch.config.payload_variant.power.ls_secs = default_ls_secs;
break;
case Config_network_tag:
fromRadioScratch.config.which_payload_variant = Config_network_tag;
fromRadioScratch.config.payload_variant.network = config.network;
break;
case Config_display_tag:
fromRadioScratch.config.which_payload_variant = Config_display_tag;
fromRadioScratch.config.payload_variant.display = config.display;
break;
case Config_lora_tag:
fromRadioScratch.config.which_payload_variant = Config_lora_tag;
fromRadioScratch.config.payload_variant.lora = config.lora;
break;
case Config_bluetooth_tag:
fromRadioScratch.config.which_payload_variant = Config_bluetooth_tag;
fromRadioScratch.config.payload_variant.bluetooth = config.bluetooth;
break;
case Config_device_tag:
fromRadioScratch.config.which_payload_variant = Config_device_tag;
fromRadioScratch.config.payload_variant.device = config.device;
break;
case Config_position_tag:
fromRadioScratch.config.which_payload_variant = Config_position_tag;
fromRadioScratch.config.payload_variant.position = config.position;
break;
case Config_power_tag:
fromRadioScratch.config.which_payload_variant = Config_power_tag;
fromRadioScratch.config.payload_variant.power = config.power;
fromRadioScratch.config.payload_variant.power.ls_secs = default_ls_secs;
break;
case Config_network_tag:
fromRadioScratch.config.which_payload_variant = Config_network_tag;
fromRadioScratch.config.payload_variant.network = config.network;
break;
case Config_display_tag:
fromRadioScratch.config.which_payload_variant = Config_display_tag;
fromRadioScratch.config.payload_variant.display = config.display;
break;
case Config_lora_tag:
fromRadioScratch.config.which_payload_variant = Config_lora_tag;
fromRadioScratch.config.payload_variant.lora = config.lora;
break;
case Config_bluetooth_tag:
fromRadioScratch.config.which_payload_variant = Config_bluetooth_tag;
fromRadioScratch.config.payload_variant.bluetooth = config.bluetooth;
break;
}
// NOTE: The phone app needs to know the ls_secs value so it can properly expect sleep behavior.
// So even if we internally use 0 to represent 'use default' we still need to send the value we are
// using to the app (so that even old phone apps work with new device loads).
config_state++;
// Advance when we have sent all of our config objects
if (config_state > Config_bluetooth_tag) {
@@ -211,37 +225,37 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
DEBUG_MSG("getFromRadio=STATE_SEND_MODULECONFIG\n");
fromRadioScratch.which_payload_variant = FromRadio_moduleConfig_tag;
switch (config_state) {
case ModuleConfig_mqtt_tag:
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_mqtt_tag;
fromRadioScratch.moduleConfig.payload_variant.mqtt = moduleConfig.mqtt;
break;
case ModuleConfig_serial_tag:
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_serial_tag;
fromRadioScratch.moduleConfig.payload_variant.serial = moduleConfig.serial;
break;
case ModuleConfig_external_notification_tag:
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_external_notification_tag;
fromRadioScratch.moduleConfig.payload_variant.external_notification = moduleConfig.external_notification;
break;
case ModuleConfig_range_test_tag:
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_range_test_tag;
fromRadioScratch.moduleConfig.payload_variant.range_test = moduleConfig.range_test;
break;
case ModuleConfig_telemetry_tag:
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_telemetry_tag;
fromRadioScratch.moduleConfig.payload_variant.telemetry = moduleConfig.telemetry;
break;
case ModuleConfig_canned_message_tag:
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_canned_message_tag;
fromRadioScratch.moduleConfig.payload_variant.canned_message = moduleConfig.canned_message;
break;
case ModuleConfig_mqtt_tag:
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_mqtt_tag;
fromRadioScratch.moduleConfig.payload_variant.mqtt = moduleConfig.mqtt;
break;
case ModuleConfig_serial_tag:
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_serial_tag;
fromRadioScratch.moduleConfig.payload_variant.serial = moduleConfig.serial;
break;
case ModuleConfig_external_notification_tag:
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_external_notification_tag;
fromRadioScratch.moduleConfig.payload_variant.external_notification = moduleConfig.external_notification;
break;
case ModuleConfig_range_test_tag:
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_range_test_tag;
fromRadioScratch.moduleConfig.payload_variant.range_test = moduleConfig.range_test;
break;
case ModuleConfig_telemetry_tag:
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_telemetry_tag;
fromRadioScratch.moduleConfig.payload_variant.telemetry = moduleConfig.telemetry;
break;
case ModuleConfig_canned_message_tag:
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_canned_message_tag;
fromRadioScratch.moduleConfig.payload_variant.canned_message = moduleConfig.canned_message;
break;
}
config_state++;
// Advance when we have sent all of our ModuleConfig objects
if (config_state > ModuleConfig_canned_message_tag) {
state = STATE_SEND_COMPLETE_ID;
config_state = Config_device_tag;
config_state = 0;
}
break;
@@ -274,7 +288,8 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
if (fromRadioScratch.which_payload_variant != 0) {
// Encapsulate as a FromRadio packet
size_t numbytes = pb_encode_to_bytes(buf, FromRadio_size, FromRadio_fields, &fromRadioScratch);
// DEBUG_MSG("encoding toPhone packet to phone variant=%d, %d bytes\n", fromRadioScratch.which_payloadVariant, numbytes);
DEBUG_MSG("encoding toPhone packet to phone variant=%d, %d bytes\n", fromRadioScratch.which_payload_variant, numbytes);
return numbytes;
}
@@ -282,7 +297,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
return 0;
}
void PhoneAPI::handleDisconnect()
void PhoneAPI::handleDisconnect()
{
DEBUG_MSG("PhoneAPI disconnect\n");
}
@@ -301,26 +316,25 @@ void PhoneAPI::releasePhonePacket()
bool PhoneAPI::available()
{
switch (state) {
case STATE_SEND_NOTHING:
return false;
case STATE_SEND_MY_INFO:
return true;
case STATE_SEND_CONFIG:
return true;
case STATE_SEND_MODULECONFIG:
return true;
case STATE_SEND_NODEINFO:
if (!nodeInfoForPhone)
nodeInfoForPhone = nodeDB.readNextInfo();
return true; // Always say we have something, because we might need to advance our state machine
case STATE_SEND_COMPLETE_ID:
return true;
case STATE_SEND_PACKETS: {
if (!packetForPhone)
packetForPhone = service.getForPhone();
bool hasPacket = !!packetForPhone;
// DEBUG_MSG("available hasPacket=%d\n", hasPacket);
return hasPacket;
case STATE_SEND_NOTHING:
return false;
case STATE_SEND_MY_INFO:
case STATE_SEND_CHANNELS:
case STATE_SEND_CONFIG:
case STATE_SEND_MODULECONFIG:
case STATE_SEND_COMPLETE_ID:
return true;
case STATE_SEND_NODEINFO:
if (!nodeInfoForPhone)
nodeInfoForPhone = nodeDB.readNextInfo();
return true; // Always say we have something, because we might need to advance our state machine
case STATE_SEND_PACKETS: {
if (!packetForPhone)
packetForPhone = service.getForPhone();
bool hasPacket = !!packetForPhone;
// DEBUG_MSG("available hasPacket=%d\n", hasPacket);
return hasPacket;
}
default:
assert(0); // unexpected state - FIXME, make an error code and reboot

View File

@@ -16,13 +16,13 @@
* Eventually there should be once instance of this class for each live connection (because it has a bit of state
* for that connection)
*/
class PhoneAPI
: public Observer<uint32_t> // FIXME, we shouldn't be inheriting from Observer, instead use CallbackObserver as a member
class PhoneAPI : public Observer<uint32_t> // FIXME, we shouldn't be inheriting from Observer, instead use CallbackObserver as a member
{
enum State {
STATE_SEND_NOTHING, // Initial state, don't send anything until the client starts asking for config
STATE_SEND_MY_INFO, // send our my info record
STATE_SEND_NODEINFO, // states progress in this order as the device sends to to the client
STATE_SEND_CHANNELS, // Send all channels
STATE_SEND_CONFIG, // Replacement for the old Radioconfig
STATE_SEND_MODULECONFIG, // Send Module specific config
STATE_SEND_COMPLETE_ID,
@@ -31,7 +31,7 @@ class PhoneAPI
State state = STATE_SEND_NOTHING;
int8_t config_state = Config_device_tag;
uint8_t config_state = 0;
/**
* Each packet sent to the phone has an incrementing count

View File

@@ -422,7 +422,7 @@ void RadioInterface::applyModemConfig()
// If user has manually specified a channel num, then use that, otherwise generate one by hashing the name
const char *channelName = channels.getName(channels.getPrimaryIndex());
int channel_num = loraConfig.channel_num ? loraConfig.channel_num - 1 : hash(channelName) % numChannels;
int channel_num = (loraConfig.channel_num ? loraConfig.channel_num - 1 : hash(channelName)) % numChannels;
// Old frequency selection formula
// float freq = myRegion->freqStart + ((((myRegion->freqEnd - myRegion->freqStart) / numChannels) / 2) * channel_num);

View File

@@ -58,12 +58,12 @@ bool ReliableRouter::shouldFilterReceived(MeshPacket *p)
* this way if an ACK is dropped and a packet is resent we'll ACK the resent packet
* make sure wasSeenRecently _doesn't_ update
* finding the channel requires decoding the packet. */
if (p->want_ack && (p->to == getNodeNum()) && wasSeenRecently(p, false)) {
if (p->want_ack && (p->to == getNodeNum()) && wasSeenRecently(p, false) && !MeshModule::currentReply) {
if (perhapsDecode(p)) {
sendAckNak(Routing_Error_NONE, getFrom(p), p->id, p->channel);
DEBUG_MSG("acking a repeated want_ack packet\n");
}
} else if (wasSeenRecently(p, false) && p->hop_limit == HOP_RELIABLE) {
} else if (wasSeenRecently(p, false) && p->hop_limit == HOP_RELIABLE && !MeshModule::currentReply) {
// retransmission on broadcast has hop_limit still equal to HOP_RELIABLE
DEBUG_MSG("Resending implicit ack for a repeated floodmsg\n");
MeshPacket *tosend = packetPool.allocCopy(*p);
@@ -94,7 +94,7 @@ void ReliableRouter::sniffReceived(const MeshPacket *p, const Routing *c)
// - not DSR routing)
if (p->want_ack) {
if (MeshModule::currentReply)
DEBUG_MSG("Someone else has replied to this message, no need for a 2nd ack\n");
DEBUG_MSG("Some other module has replied to this message, no need for a 2nd ack\n");
else
sendAckNak(Routing_Error_NONE, getFrom(p), p->id, p->channel);
}

View File

@@ -18,6 +18,9 @@ class SinglePortModule : public MeshModule
SinglePortModule(const char *_name, PortNum _ourPortNum) : MeshModule(_name), ourPortNum(_ourPortNum) {}
protected:
uint32_t max_channel_util_percent = 40;
uint32_t polite_channel_util_percent = 25;
/**
* @return true if you want to receive the specified portnum
*/

View File

@@ -59,14 +59,12 @@ typedef struct _AdminMessage {
AdminMessage_ModuleConfigType get_module_config_request;
/* Send the current Config in the response to this message. */
ModuleConfig get_module_config_response;
/* Send all channels in the response to this message */
bool get_all_channel_request;
/* Get the Canned Message Module messages in the response to this message. */
bool get_canned_message_module_messages_request;
/* Get the Canned Message Module messages in the response to this message. */
char get_canned_message_module_messages_response[201];
/* Request the node to send device metadata (firmware, protobuf version, etc) */
uint32_t get_device_metadata_request;
bool get_device_metadata_request;
/* Device metadata response */
DeviceMetadata get_device_metadata_response;
/* Set the owner for this node */
@@ -94,6 +92,9 @@ typedef struct _AdminMessage {
bool confirm_set_channel;
/* TODO: REPLACE */
bool confirm_set_radio;
/* Tell the node to reboot into the OTA Firmware in this many seconds (or <0 to cancel reboot)
Only Implemented for ESP32 Devices. This needs to be issued to send a new main firmware via bluetooth. */
int32_t reboot_ota_seconds;
/* This message is only supported for the simulator porduino build.
If received the simulator will exit successfully. */
bool exit_simulator;
@@ -136,7 +137,6 @@ extern "C" {
#define AdminMessage_get_config_response_tag 6
#define AdminMessage_get_module_config_request_tag 7
#define AdminMessage_get_module_config_response_tag 8
#define AdminMessage_get_all_channel_request_tag 9
#define AdminMessage_get_canned_message_module_messages_request_tag 10
#define AdminMessage_get_canned_message_module_messages_response_tag 11
#define AdminMessage_get_device_metadata_request_tag 12
@@ -150,6 +150,7 @@ extern "C" {
#define AdminMessage_confirm_set_module_config_tag 65
#define AdminMessage_confirm_set_channel_tag 66
#define AdminMessage_confirm_set_radio_tag 67
#define AdminMessage_reboot_ota_seconds_tag 95
#define AdminMessage_exit_simulator_tag 96
#define AdminMessage_reboot_seconds_tag 97
#define AdminMessage_shutdown_seconds_tag 98
@@ -166,10 +167,9 @@ X(a, STATIC, ONEOF, UENUM, (payload_variant,get_config_request,get_confi
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,get_config_response,get_config_response), 6) \
X(a, STATIC, ONEOF, UENUM, (payload_variant,get_module_config_request,get_module_config_request), 7) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,get_module_config_response,get_module_config_response), 8) \
X(a, STATIC, ONEOF, BOOL, (payload_variant,get_all_channel_request,get_all_channel_request), 9) \
X(a, STATIC, ONEOF, BOOL, (payload_variant,get_canned_message_module_messages_request,get_canned_message_module_messages_request), 10) \
X(a, STATIC, ONEOF, STRING, (payload_variant,get_canned_message_module_messages_response,get_canned_message_module_messages_response), 11) \
X(a, STATIC, ONEOF, UINT32, (payload_variant,get_device_metadata_request,get_device_metadata_request), 12) \
X(a, STATIC, ONEOF, BOOL, (payload_variant,get_device_metadata_request,get_device_metadata_request), 12) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,get_device_metadata_response,get_device_metadata_response), 13) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,set_owner,set_owner), 32) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,set_channel,set_channel), 33) \
@@ -180,6 +180,7 @@ X(a, STATIC, ONEOF, BOOL, (payload_variant,confirm_set_config,confirm_s
X(a, STATIC, ONEOF, BOOL, (payload_variant,confirm_set_module_config,confirm_set_module_config), 65) \
X(a, STATIC, ONEOF, BOOL, (payload_variant,confirm_set_channel,confirm_set_channel), 66) \
X(a, STATIC, ONEOF, BOOL, (payload_variant,confirm_set_radio,confirm_set_radio), 67) \
X(a, STATIC, ONEOF, INT32, (payload_variant,reboot_ota_seconds,reboot_ota_seconds), 95) \
X(a, STATIC, ONEOF, BOOL, (payload_variant,exit_simulator,exit_simulator), 96) \
X(a, STATIC, ONEOF, INT32, (payload_variant,reboot_seconds,reboot_seconds), 97) \
X(a, STATIC, ONEOF, INT32, (payload_variant,shutdown_seconds,shutdown_seconds), 98) \

View File

@@ -4,6 +4,7 @@
#ifndef PB_MESH_PB_H_INCLUDED
#define PB_MESH_PB_H_INCLUDED
#include <pb.h>
#include "channel.pb.h"
#include "config.pb.h"
#include "module_config.pb.h"
#include "portnums.pb.h"
@@ -652,6 +653,8 @@ typedef struct _FromRadio {
bool rebooted;
/* Include module config */
ModuleConfig moduleConfig;
/* One packet is sent for each channel */
Channel channel;
};
} FromRadio;
@@ -854,6 +857,7 @@ extern "C" {
#define FromRadio_config_complete_id_tag 7
#define FromRadio_rebooted_tag 8
#define FromRadio_moduleConfig_tag 9
#define FromRadio_channel_tag 10
#define ToRadio_packet_tag 1
#define ToRadio_peer_info_tag 2
#define ToRadio_want_config_id_tag 3
@@ -1001,7 +1005,8 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,config,config), 5) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,log_record,log_record), 6) \
X(a, STATIC, ONEOF, UINT32, (payload_variant,config_complete_id,config_complete_id), 7) \
X(a, STATIC, ONEOF, BOOL, (payload_variant,rebooted,rebooted), 8) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,moduleConfig,moduleConfig), 9)
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,moduleConfig,moduleConfig), 9) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,channel,channel), 10)
#define FromRadio_CALLBACK NULL
#define FromRadio_DEFAULT NULL
#define FromRadio_payload_variant_packet_MSGTYPE MeshPacket
@@ -1010,6 +1015,7 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,moduleConfig,moduleConfig),
#define FromRadio_payload_variant_config_MSGTYPE Config
#define FromRadio_payload_variant_log_record_MSGTYPE LogRecord
#define FromRadio_payload_variant_moduleConfig_MSGTYPE ModuleConfig
#define FromRadio_payload_variant_channel_MSGTYPE Channel
#define ToRadio_FIELDLIST(X, a) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,packet,packet), 1) \

View File

@@ -29,7 +29,11 @@ typedef enum _TelemetrySensorType {
/* High accuracy temperature and humidity */
TelemetrySensorType_SHTC3 = 7,
/* High accuracy pressure */
TelemetrySensorType_LPS22 = 8
TelemetrySensorType_LPS22 = 8,
/* 3-Axis magnetic sensor */
TelemetrySensorType_QMC6310 = 9,
/* 6-Axis inertial measurement sensor */
TelemetrySensorType_QMI8658 = 10
} TelemetrySensorType;
/* Struct definitions */
@@ -81,8 +85,8 @@ typedef struct _Telemetry {
/* Helper constants for enums */
#define _TelemetrySensorType_MIN TelemetrySensorType_SENSOR_UNSET
#define _TelemetrySensorType_MAX TelemetrySensorType_LPS22
#define _TelemetrySensorType_ARRAYSIZE ((TelemetrySensorType)(TelemetrySensorType_LPS22+1))
#define _TelemetrySensorType_MAX TelemetrySensorType_QMI8658
#define _TelemetrySensorType_ARRAYSIZE ((TelemetrySensorType)(TelemetrySensorType_QMI8658+1))
#ifdef __cplusplus

View File

@@ -2,6 +2,9 @@
#include "Channels.h"
#include "MeshService.h"
#include "NodeDB.h"
#ifdef ARCH_ESP32
#include "BleOta.h"
#endif
#include "Router.h"
#include "configuration.h"
#include "main.h"
@@ -103,6 +106,21 @@ bool AdminModule::handleReceivedProtobuf(const MeshPacket &mp, AdminMessage *r)
rebootAtMsec = (s < 0) ? 0 : (millis() + s * 1000);
break;
}
case AdminMessage_reboot_ota_seconds_tag: {
int32_t s = r->reboot_ota_seconds;
#ifdef ARCH_ESP32
if (BleOta::getOtaAppVersion().isEmpty()) {
DEBUG_MSG("No OTA firmware available, scheduling regular reboot in %d seconds\n", s);
}else{
BleOta::switchToOtaApp();
DEBUG_MSG("Rebooting to OTA in %d seconds\n", s);
}
#else
DEBUG_MSG("Not on ESP32, scheduling regular reboot in %d seconds\n", s);
#endif
rebootAtMsec = (s < 0) ? 0 : (millis() + s * 1000);
break;
}
case AdminMessage_shutdown_seconds_tag: {
int32_t s = r->shutdown_seconds;
DEBUG_MSG("Shutdown in %d seconds\n", s);

View File

@@ -2,6 +2,7 @@
#if HAS_SCREEN
#include "CannedMessageModule.h"
#include "FSCommon.h"
#include "NodeDB.h"
#include "MeshService.h"
#include "PowerFSM.h" // neede for button bypass
#include "mesh/generated/cannedmessages.pb.h"
@@ -10,7 +11,7 @@
#include "graphics/fonts/OLEDDisplayFontsRU.h"
#endif
#if defined(USE_EINK) || defined(ILI9341_DRIVER)
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS)
// The screen is bigger so use bigger fonts
#define FONT_SMALL ArialMT_Plain_16
#define FONT_MEDIUM ArialMT_Plain_24
@@ -202,7 +203,7 @@ void CannedMessageModule::sendText(NodeNum dest, const char *message, bool wantR
p->decoded.payload.size++;
}
DEBUG_MSG("Sending message id=%d, msg=%.*s\n", p->id, p->decoded.payload.size, p->decoded.payload.bytes);
DEBUG_MSG("Sending message id=%d, dest=%x, msg=%.*s\n", p->id, p->to, p->decoded.payload.size, p->decoded.payload.bytes);
service.sendToMesh(p);
}
@@ -222,25 +223,26 @@ int32_t CannedMessageModule::runOnce()
this->currentMessageIndex = -1;
this->freetext = ""; // clear freetext
this->cursor = 0;
this->destSelect = false;
this->notifyObservers(&e);
} else if (((this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) || (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT)) && (millis() - this->lastTouchMillis) > INACTIVATE_AFTER_MS) {
} else if (((this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) || (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT)) && ((millis() - this->lastTouchMillis) > INACTIVATE_AFTER_MS)) {
// Reset module
DEBUG_MSG("Reset due to lack of activity.\n");
e.frameChanged = true;
this->currentMessageIndex = -1;
this->freetext = ""; // clear freetext
this->cursor = 0;
this->destSelect = false;
this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
this->notifyObservers(&e);
} else if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTION_SELECT) {
if (this->payload == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
if (this->freetext.length() > 0) {
sendText(NODENUM_BROADCAST, this->freetext.c_str(), true);
sendText(this->dest, this->freetext.c_str(), true);
this->runState = CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE;
} else {
DEBUG_MSG("Reset message is empty.\n");
this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
e.frameChanged = true;
}
} else {
if ((this->messagesCount > this->currentMessageIndex) && (strlen(this->messages[this->currentMessageIndex]) > 0)) {
@@ -249,12 +251,13 @@ int32_t CannedMessageModule::runOnce()
} else {
DEBUG_MSG("Reset message is empty.\n");
this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
e.frameChanged = true;
}
}
e.frameChanged = true;
this->currentMessageIndex = -1;
this->freetext = ""; // clear freetext
this->cursor = 0;
this->destSelect = false;
this->notifyObservers(&e);
return 2000;
} else if ((this->runState != CANNED_MESSAGE_RUN_STATE_FREETEXT) && (this->currentMessageIndex == -1)) {
@@ -263,31 +266,69 @@ int32_t CannedMessageModule::runOnce()
e.frameChanged = true;
this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE;
} else if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTION_UP) {
this->currentMessageIndex = getPrevIndex();
this->freetext = ""; // clear freetext
this->cursor = 0;
this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE;
DEBUG_MSG("MOVE UP (%d):%s\n", this->currentMessageIndex, this->getCurrentMessage());
if (this->messagesCount > 0) {
this->currentMessageIndex = getPrevIndex();
this->freetext = ""; // clear freetext
this->cursor = 0;
this->destSelect = false;
this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE;
DEBUG_MSG("MOVE UP (%d):%s\n", this->currentMessageIndex, this->getCurrentMessage());
}
} else if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTION_DOWN) {
this->currentMessageIndex = this->getNextIndex();
this->freetext = ""; // clear freetext
this->cursor = 0;
this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE;
DEBUG_MSG("MOVE DOWN (%d):%s\n", this->currentMessageIndex, this->getCurrentMessage());
if (this->messagesCount > 0) {
this->currentMessageIndex = this->getNextIndex();
this->freetext = ""; // clear freetext
this->cursor = 0;
this->destSelect = false;
this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE;
DEBUG_MSG("MOVE DOWN (%d):%s\n", this->currentMessageIndex, this->getCurrentMessage());
}
} else if (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
e.frameChanged = true;
switch (this->payload) {
case 0xb4: // left
if (this->cursor > 0) {
this->cursor--;
if (this->destSelect){
size_t numNodes = nodeDB.getNumNodes();
if(this->dest == NODENUM_BROADCAST) {
this->dest = nodeDB.getNodeNum();
}
for (unsigned int i = 0; i < numNodes; i++) {
if (nodeDB.getNodeByIndex(i)->num == this->dest) {
this->dest = (i > 0) ? nodeDB.getNodeByIndex(i-1)->num : nodeDB.getNodeByIndex(numNodes-1)->num;
break;
}
}
if(this->dest == nodeDB.getNodeNum()) {
this->dest = NODENUM_BROADCAST;
}
}else{
if (this->cursor > 0) {
this->cursor--;
}
}
break;
case 0xb7: // right
if (this->cursor < this->freetext.length()) {
this->cursor++;
if (this->destSelect){
size_t numNodes = nodeDB.getNumNodes();
if(this->dest == NODENUM_BROADCAST) {
this->dest = nodeDB.getNodeNum();
}
for (unsigned int i = 0; i < numNodes; i++) {
if (nodeDB.getNodeByIndex(i)->num == this->dest) {
this->dest = (i < numNodes-1) ? nodeDB.getNodeByIndex(i+1)->num : nodeDB.getNodeByIndex(0)->num;
break;
}
}
if(this->dest == nodeDB.getNodeNum()) {
this->dest = NODENUM_BROADCAST;
}
}else{
if (this->cursor < this->freetext.length()) {
this->cursor++;
}
}
break;
case 8: // backspace
case 0x08: // backspace
if (this->freetext.length() > 0) {
if(this->cursor == this->freetext.length()) {
this->freetext = this->freetext.substring(0, this->freetext.length() - 1);
@@ -297,6 +338,13 @@ int32_t CannedMessageModule::runOnce()
this->cursor--;
}
break;
case 0x09: // tab
if(this->destSelect) {
this->destSelect = false;
} else {
this->destSelect = true;
}
break;
default:
if(this->cursor == this->freetext.length()) {
this->freetext += this->payload;
@@ -339,6 +387,19 @@ const char *CannedMessageModule::getNextMessage()
{
return this->messages[this->getNextIndex()];
}
const char* CannedMessageModule::getNodeName(NodeNum node) {
if (node == NODENUM_BROADCAST){
return "Broadcast";
}else{
NodeInfo *info = nodeDB.getNode(node);
if(info != NULL) {
return info->user.long_name;
}else{
return "Unknown";
}
}
}
bool CannedMessageModule::shouldDraw()
{
if (!moduleConfig.canned_message.enabled) {
@@ -369,6 +430,8 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
{
displayedNodeNum = 0; // Not currently showing a node pane
char buffer[50];
if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE) {
display->setTextAlignment(TEXT_ALIGN_CENTER);
display->setFont(FONT_MEDIUM);
@@ -379,21 +442,29 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
display->drawString(10 + x, 0 + y + FONT_HEIGHT_SMALL, "Canned Message\nModule disabled.");
}else if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(FONT_MEDIUM);
display->drawString(0 + x, 0 + y, "To: Broadcast");
display->setFont(FONT_SMALL);
if (this->destSelect) {
display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL);
display->setColor(BLACK);
}
display->drawStringf(0 + x, 0 + y, buffer, "To: %s", cannedMessageModule->getNodeName(this->dest));
// used chars right aligned
char buffer[9];
sprintf(buffer, "%d left", Constants_DATA_PAYLOAD_LEN - this->freetext.length());
display->drawString(x + display->getWidth() - display->getStringWidth(buffer), y + 0, buffer);
display->drawString(0 + x, 0 + y + FONT_HEIGHT_MEDIUM, cannedMessageModule->drawWithCursor(cannedMessageModule->freetext, cannedMessageModule->cursor));
display->setColor(WHITE);
display->drawStringMaxWidth(0 + x, 0 + y + FONT_HEIGHT_SMALL, x + display->getWidth(), cannedMessageModule->drawWithCursor(cannedMessageModule->freetext, cannedMessageModule->cursor));
} else {
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(FONT_SMALL);
display->drawString(0 + x, 0 + y, cannedMessageModule->getPrevMessage());
display->setFont(FONT_MEDIUM);
display->drawString(0 + x, 0 + y + FONT_HEIGHT_SMALL, cannedMessageModule->getCurrentMessage());
display->setFont(FONT_SMALL);
display->drawString(0 + x, 0 + y + FONT_HEIGHT_MEDIUM, cannedMessageModule->getNextMessage());
if (this->messagesCount > 0) {
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(FONT_SMALL);
display->drawStringf(0 + x, 0 + y, buffer, "To: %s", cannedMessageModule->getNodeName(this->dest));
display->drawString(0 + x, 0 + y + FONT_HEIGHT_SMALL, cannedMessageModule->getPrevMessage());
display->fillRect(0 + x, 0 + y + FONT_HEIGHT_SMALL * 2, x + display->getWidth(), y + FONT_HEIGHT_SMALL);
display->setColor(BLACK);
display->drawString(0 + x, 0 + y + FONT_HEIGHT_SMALL * 2, cannedMessageModule->getCurrentMessage());
display->setColor(WHITE);
display->drawString(0 + x, 0 + y + FONT_HEIGHT_SMALL * 3, cannedMessageModule->getNextMessage());
}
}
}

View File

@@ -9,7 +9,6 @@ enum cannedMessageModuleRunState
CANNED_MESSAGE_RUN_STATE_INACTIVE,
CANNED_MESSAGE_RUN_STATE_ACTIVE,
CANNED_MESSAGE_RUN_STATE_FREETEXT,
CANNED_MESSAGE_RUN_STATE_MATRIX,
CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE,
CANNED_MESSAGE_RUN_STATE_ACTION_SELECT,
CANNED_MESSAGE_RUN_STATE_ACTION_UP,
@@ -36,6 +35,7 @@ class CannedMessageModule :
const char* getCurrentMessage();
const char* getPrevMessage();
const char* getNextMessage();
const char* getNodeName(NodeNum node);
bool shouldDraw();
void eventUp();
void eventDown();
@@ -74,9 +74,11 @@ class CannedMessageModule :
int currentMessageIndex = -1;
cannedMessageModuleRunState runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
char payload;
char payload = 0x00;
unsigned int cursor = 0;
String freetext = ""; // Text Buffer for Freetext Editor
bool destSelect = false; // Freetext Editor Mode
NodeNum dest = NODENUM_BROADCAST;
char messageStore[CANNED_MESSAGE_MODULE_MESSAGES_SIZE+1];
char *messages[CANNED_MESSAGE_MODULE_MESSAGE_MAX_COUNT];
@@ -85,4 +87,4 @@ class CannedMessageModule :
};
extern CannedMessageModule *cannedMessageModule;
#endif
#endif

View File

@@ -144,7 +144,7 @@ int32_t PositionModule::runOnce()
if (lastGpsSend == 0 || (now - lastGpsSend) >= intervalMs) {
// Only send packets if the channel is less than 40% utilized.
if (airTime->channelUtilizationPercent() < 40) {
if (airTime->channelUtilizationPercent() < max_channel_util_percent) {
if (node->has_position && (node->position.latitude_i != 0 || node->position.longitude_i != 0)) {
lastGpsSend = now;
@@ -165,7 +165,7 @@ int32_t PositionModule::runOnce()
} else if (config.position.position_broadcast_smart_enabled) {
// Only send packets if the channel is less than 25% utilized.
if (airTime->channelUtilizationPercent() < 25) {
if (airTime->channelUtilizationPercent() < polite_channel_util_percent) {
NodeInfo *node2 = service.refreshMyNodeInfo(); // should guarantee there is now a position

View File

@@ -13,15 +13,16 @@
int32_t DeviceTelemetryModule::runOnce()
{
#ifndef ARCH_PORTDUINO
if (firstTime) {
// This is the first time the OSThread library has called this function, so do some setup
firstTime = 0;
DEBUG_MSG("Device Telemetry: Initializing\n");
uint32_t now = millis();
if ((lastSentToMesh == 0 || (now - lastSentToMesh) >= getConfiguredOrDefaultMs(moduleConfig.telemetry.device_update_interval))
&& airTime->channelUtilizationPercent() < max_channel_util_percent) {
sendTelemetry();
lastSentToMesh = now;
} else {
// Just send to phone when it's not our time to send to mesh yet
sendTelemetry(NODENUM_BROADCAST, true);
}
sendOurTelemetry();
// OSThread library. Multiply the preference value by 1000 to convert seconds to miliseconds
return getConfiguredOrDefaultMs(moduleConfig.telemetry.device_update_interval);
return sendToPhoneIntervalMs;
#endif
}
@@ -45,7 +46,7 @@ bool DeviceTelemetryModule::handleReceivedProtobuf(const MeshPacket &mp, Telemet
return false; // Let others look at this message also if they want
}
bool DeviceTelemetryModule::sendOurTelemetry(NodeNum dest, bool wantReplies)
bool DeviceTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
{
Telemetry t;
@@ -68,11 +69,16 @@ bool DeviceTelemetryModule::sendOurTelemetry(NodeNum dest, bool wantReplies)
MeshPacket *p = allocDataProtobuf(t);
p->to = dest;
p->decoded.want_response = wantReplies;
p->decoded.want_response = false;
lastMeasurementPacket = packetPool.allocCopy(*p);
DEBUG_MSG("Device Telemetry: Sending packet to mesh\n");
service.sendToMesh(p, RX_SRC_LOCAL, true);
nodeDB.updateTelemetry(nodeDB.getNodeNum(), t, RX_SRC_LOCAL);
if (phoneOnly) {
DEBUG_MSG("Device Telemetry: Sending packet to phone\n");
service.sendToPhone(p);
} else {
DEBUG_MSG("Device Telemetry: Sending packet to mesh\n");
service.sendToMesh(p, RX_SRC_LOCAL, true);
}
return true;
}

View File

@@ -24,9 +24,10 @@ class DeviceTelemetryModule : private concurrency::OSThread, public ProtobufModu
/**
* Send our Telemetry into the mesh
*/
bool sendOurTelemetry(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false);
bool sendTelemetry(NodeNum dest = NODENUM_BROADCAST, bool phoneOnly = false);
private:
bool firstTime = 1;
uint32_t sendToPhoneIntervalMs = SECONDS_IN_MINUTE * 1000; // Send to phone every minute
uint32_t lastSentToMesh = 0;
const MeshPacket *lastMeasurementPacket;
};

View File

@@ -27,7 +27,7 @@ int32_t StoreForwardModule::runOnce()
if (this->busy) {
// Only send packets if the channel is less than 25% utilized.
if (airTime->channelUtilizationPercent() < 25) {
if (airTime->channelUtilizationPercent() < polite_channel_util_percent) {
// DEBUG_MSG("--- --- --- In busy loop 1 %d\n", this->packetHistoryTXQueue_index);
storeForwardModule->sendPayload(this->busyTo, this->packetHistoryTXQueue_index);

View File

@@ -14,9 +14,9 @@
MQTT *mqtt;
String statusTopic = "msh/1/stat/";
String cryptTopic = "msh/1/c/"; // msh/1/c/CHANNELID/NODEID
String jsonTopic = "msh/1/json/"; // msh/1/json/CHANNELID/NODEID
String statusTopic = "msh/2/stat/";
String cryptTopic = "msh/2/c/"; // msh/2/c/CHANNELID/NODEID
String jsonTopic = "msh/2/json/"; // msh/2/json/CHANNELID/NODEID
void MQTT::mqttCallback(char *topic, byte *payload, unsigned int length)
{

View File

@@ -0,0 +1,43 @@
#include "Arduino.h"
#include "BleOta.h"
#include <esp_ota_ops.h>
static const String MESHTASTIC_OTA_APP_PROJECT_NAME("Meshtastic-OTA");
const esp_partition_t* BleOta::findEspOtaAppPartition() {
const esp_partition_t *part = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_OTA_0, nullptr);
esp_app_desc_t app_desc;
esp_err_t ret = ESP_ERROR_CHECK_WITHOUT_ABORT(esp_ota_get_partition_description(part, &app_desc));
if (ret != ESP_OK || MESHTASTIC_OTA_APP_PROJECT_NAME != app_desc.project_name) {
part = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_OTA_1, nullptr);
ret = ESP_ERROR_CHECK_WITHOUT_ABORT(esp_ota_get_partition_description(part, &app_desc));
}
if (ret == ESP_OK && MESHTASTIC_OTA_APP_PROJECT_NAME == app_desc.project_name) {
return part;
} else {
return nullptr;
}
}
String BleOta::getOtaAppVersion() {
const esp_partition_t *part = findEspOtaAppPartition();
esp_app_desc_t app_desc;
esp_err_t ret = ESP_ERROR_CHECK_WITHOUT_ABORT(esp_ota_get_partition_description(part, &app_desc));
String version;
if (ret == ESP_OK) {
version = app_desc.version;
}
return version;
}
bool BleOta::switchToOtaApp() {
bool success = false;
const esp_partition_t *part = findEspOtaAppPartition();
if (part) {
success = (ESP_ERROR_CHECK_WITHOUT_ABORT(esp_ota_set_boot_partition(part)) == ESP_OK);
}
return success;
}

View File

@@ -0,0 +1,18 @@
#ifndef BLEOTA_H
#define BLEOTA_H
#include <functional>
class BleOta {
public:
explicit BleOta() {};
static String getOtaAppVersion();
static bool switchToOtaApp();
private:
String mUserAgent;
static const esp_partition_t *findEspOtaAppPartition();
};
#endif //BLEOTA_H

View File

@@ -4,6 +4,7 @@
#include "main.h"
#include "nimble/NimbleBluetooth.h"
#include "BleOta.h"
#include "mesh/http/WiFiAPClient.h"
#include "sleep.h"
@@ -63,6 +64,12 @@ void esp32Setup()
preferences.putUInt("rebootCounter", rebootCounter);
preferences.end();
DEBUG_MSG("Number of Device Reboots: %d\n", rebootCounter);
String BLEOTA=BleOta::getOtaAppVersion();
if (BLEOTA.isEmpty()) {
DEBUG_MSG("No OTA firmware available\n");
}else{
DEBUG_MSG("OTA firmware version %s\n", BLEOTA);
}
// enableModemSleep();

View File

@@ -244,6 +244,9 @@ void NRF52Bluetooth::setup()
Bluefruit.Periph.setConnectCallback(onConnect);
Bluefruit.Periph.setDisconnectCallback(onDisconnect);
bledfu.setPermission(SECMODE_ENC_WITH_MITM, SECMODE_ENC_WITH_MITM);
bledfu.begin(); // Install the DFU helper
// Configure and Start the Device Information Service
DEBUG_MSG("Configuring the Device Information Service\n");
bledis.setModel(optstr(HW_VERSION));
@@ -254,7 +257,7 @@ void NRF52Bluetooth::setup()
DEBUG_MSG("Configuring the Battery Service\n");
blebas.begin();
blebas.write(0); // Unknown battery level for now
bledfu.begin(); // Install the DFU helper
// Setup the Heart Rate Monitor service using
// BLEService and BLECharacteristic classes

View File

@@ -171,6 +171,8 @@ void SimRadio::onNotify(uint32_t notification)
// Packet has been sent, count it toward our TX airtime utilization.
uint32_t xmitMsec = getPacketTime(txp);
airTime->logAirtime(TX_LOG, xmitMsec);
delay(xmitMsec); // Model the time it is busy sending
completeSending();
}
}
@@ -207,6 +209,9 @@ void SimRadio::startSend(MeshPacket * txp)
void SimRadio::startReceive(MeshPacket *p) {
isReceiving = true;
size_t length = getPacketLength(p);
uint32_t xmitMsec = getPacketTime(length);
delay(xmitMsec); // Model the time it is busy receiving
handleReceiveInterrupt(p);
}

View File

@@ -23,6 +23,7 @@ build_flags =
-DTFT_BL=32
-DSPI_FREQUENCY=40000000
-DSPI_READ_FREQUENCY=16000000
-DDISABLE_ALL_LIBRARY_WARNINGS
lib_ignore =
m5stack-core
lib_deps =

View File

@@ -12,8 +12,7 @@ build_flags =
lib_deps =
${esp32_base.lib_deps}
zinggjm/GxEPD2@^1.4.9
# lewisxhe/PCF8563_Library@^1.0.1 // switch to this one when it is released!
https://github.com/lewisxhe/PCF8563_Library.git#fe8cface109f63b5a4fb6abeaf87c6de0faa24c6
lewisxhe/PCF8563_Library@^1.0.1
board_build.f_cpu = 240000000L
upload_protocol = esptool
upload_port = /dev/ttyACM*

View File

@@ -1,12 +1,12 @@
[env:pico]
extends = rp2040_base
board = pico
board = rpipico
upload_protocol = picotool
# add our variants files to the include and src paths
build_flags = ${rp2040_base.build_flags}
-DPRIVATE_HW
-Ivariants/pico
-Ivariants/rpipico
-DARDUINO_AVR_NANO_EVERY
-DDEBUG_RP2040_WIRE
-DDEBUG_RP2040_SPI

View File

@@ -0,0 +1,17 @@
[env:picow]
extends = rp2040_base
board = rpipicow
upload_protocol = picotool
# add our variants files to the include and src paths
build_flags = ${rp2040_base.build_flags}
-DPRIVATE_HW
-Ivariants/rpipicow
-DARDUINO_AVR_NANO_EVERY
-DDEBUG_RP2040_WIRE
-DDEBUG_RP2040_SPI
-DDEBUG_RP2040_CORE
-DDEBUG_RP2040_PORT=Serial
-DUSE_TINYUSB
lib_deps =
${rp2040_base.lib_deps}

View File

@@ -0,0 +1,52 @@
// #define RADIOLIB_CUSTOM_ARDUINO 1
// #define RADIOLIB_TONE_UNSUPPORTED 1
// #define RADIOLIB_SOFTWARE_SERIAL_UNSUPPORTED 1
#define ARDUINO_ARCH_AVR
#define CBC 0
#define CTR 1
#define ECB 0
#define NO_GPS 1
#define USE_SH1106 1
#undef GPS_SERIAL_NUM
// #define I2C_SDA 6
// #define I2C_SCL 7
#define BUTTON_PIN 17
#define EXT_NOTIFY_OUT 4
#define BATTERY_PIN 26
// ratio of voltage divider = 3.0 (R17=200k, R18=100k)
#define ADC_MULTIPLIER 3.1 // 3.0 + a bit for being optimistic
#define USE_RF95
#define USE_SX1262
#undef RF95_SCK
#undef RF95_MISO
#undef RF95_MOSI
#undef RF95_NSS
#define RF95_SCK 10
#define RF95_MISO 12
#define RF95_MOSI 11
#define RF95_NSS 3
#define LORA_DIO0 RADIOLIB_NC
#define LORA_RESET 15
#define LORA_DIO1 20
#define LORA_DIO2 2
#define LORA_DIO3 RADIOLIB_NC
#ifdef USE_SX1262
#define SX126X_CS RF95_NSS
#define SX126X_DIO1 LORA_DIO1
#define SX126X_BUSY LORA_DIO2
#define SX126X_RESET LORA_RESET
#define SX126X_E22
#endif
#include <Adafruit_TinyUSB.h>

View File

@@ -14,6 +14,5 @@ lib_deps =
${nrf52840_base.lib_deps}
https://github.com/meshtastic/GxEPD2#afce87a97dda1ac31d8a28dc8fa7c6f55dc96a61
adafruit/Adafruit BusIO@^1.13.2
# lewisxhe/PCF8563_Library@^1.0.1 // switch to this one when it is released!
https://github.com/lewisxhe/PCF8563_Library.git#fe8cface109f63b5a4fb6abeaf87c6de0faa24c6
lewisxhe/PCF8563_Library@^1.0.1
;upload_protocol = fs

View File

@@ -25,5 +25,12 @@ static const uint8_t MOSI = 11;
static const uint8_t MISO = 13;
static const uint8_t SCK = 12;
#define SDMMC_CMD (35)
#define SDMMC_CLK (36)
#define SDMMC_DATA (37)
#define ACCEL_INT1 (34)
#define ACCEL_INT2 (33)
#define RTC_INT (14)
#endif /* Pins_Arduino_h */

View File

@@ -5,7 +5,9 @@ board = tbeam-s3-core
lib_deps =
${esp32s3_base.lib_deps}
lewisxhe/PCF8563_Library@1.0.1
build_flags =
${esp32s3_base.build_flags}
-Ivariants/tbeam-s3-core
-DPCF8563_RTC=0x51 ;Putting definitions in variant.h does not compile correctly

View File

@@ -1,12 +1,18 @@
// #define BUTTON_NEED_PULLUP // if set we need to turn on the internal CPU pullup during sleep
#define I2C_SDA 42
#define I2C_SCL 41
#define I2C_SDA1 42 //Used for PMU management
#define I2C_SCL1 41 //Used for PMU management
#define I2C_SDA 17 //For sensors and screens
#define I2C_SCL 18 //For sensors and screens
#define BUTTON_PIN 0 // The middle button GPIO on the T-Beam S3
//#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 Module.
#define BUTTON1_PIN 47 //Additional keys
#define LED_INVERTED 1
// #define LED_PIN 4 // Newer tbeams (1.1) have an extra led on GPIO4
@@ -36,6 +42,9 @@
// #define PMU_IRQ 40
#define HAS_AXP2101
// Specify the PMU as Wire1. In the t-beam-s3-core, the PMU enjoys a separate bus
#define PMU_USE_WIRE1
#define RF95_SCK 12
#define RF95_MISO 13
#define RF95_MOSI 11
@@ -47,3 +56,10 @@
#define GPS_1PPS_PIN 6
#define HAS_SDCARD //Have 3-bit SDMMC interface SD card slot
// PCF8563 RTC Module
// #define PCF8563_RTC 0x51 //Putting definitions in variant. h does not compile correctly
#define HAS_RTC 1

View File

@@ -1,4 +1,4 @@
[VERSION]
major = 1
minor = 3
build = 42
build = 44