Compare commits

...

64 Commits

Author SHA1 Message Date
code8buster
7cebd79475 Use doNotEnterOff flag to prevent GNSS poweroff before fix acquisition (#2861)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-10-03 19:50:27 -05:00
Jonathan Bennett
aa38f53aed Fix for T-Beam 1.2 GPS (#2858)
* Fix for T-Beam 1.2 GPS, with DEBUG enabled

* Don't break other devices

* Saving GPS data on this breaks on next boot. Fix.

* derp

* disable the extra verbosity

* Try the same sort of factory reset as the Lilygo image

* Catch GPS reboots and squash

* trunk

* GPS

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-10-03 12:05:40 -05:00
Ben Meadors
2a6c8be684 Avoid problematic sleep state transitions for power saving sensors and trackers (#2860)
* Avoid problematic sleep state transitions for power saving sensors and trackers

* Line got duped :-|
2023-10-03 10:09:27 -05:00
GUVWAF
37c3d15978 Check if packet is decrypted before using portnum when converting to JSON (#2857)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-10-03 06:39:35 -05:00
Manuel
f301e236eb fix crash during shutdown (#2859)
* fix null pointer access

* ptr initialize
2023-10-03 06:37:46 -05:00
Manuel
94c2ade272 make esp32 deepsleep button wakeup functional again (#2854)
* make deepsleep button wakeup functional again

* Remove unused var

* Cleanup comment

* suppress screen wake on button

* add resume screen

* trunk fmt

* added missing #ifdef

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-10-02 16:16:29 -05:00
Ben Meadors
a6e4402e41 Screen on secs router default (#2855) 2023-10-02 06:28:05 -05:00
Jonathan Bennett
50db2d0e9b Add timeout to ublox PMREQ command (#2851) 2023-10-01 20:39:18 -05:00
Ben Meadors
5ecdbd0dbb Removed non-functional deep sleep button awake functionality (user can RST instead) (#2852)
* Fixed mask length

* Don't want_response if we're a tracker or sensor

* Fixes

* Removing non-functioning deep sleep button awake
2023-10-01 12:48:12 -05:00
Jonathan Bennett
47c6738c0d Fix GPS init bug -- power up even when disabled (#2850) 2023-09-30 23:38:51 -05:00
Ben Meadors
1552aa0081 Tracker role wakeup and sleep cycle when power.is_power_saving true (#2846)
* WIP

* Sleepy sleepy low power tracker

* Sleepy tracker clear

* NRF52 PoC

* Simplify NRF52 "sleep"

* Trackers aren't polite

* Remove unnecessary include

* Removed accidental commit

* Fixed not-so-sleepy T-Beam due to button gpio mask precendence

* Added sleepOnNextExecution for allowing fulfillment of pending messages before shutting down

* Cleanup

* Don't wantResponse for trackers

* Heltec wireless tracker doesn't like the button interrupt (maybe all s3 because user button press doubles as bootloader mode trigger?)
2023-09-30 21:09:17 -05:00
github-actions[bot]
6ebec8fcd9 [create-pull-request] automated change (#2849)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-09-30 20:40:04 -05:00
Manuel
e9215a5d70 revert KB_POWERON changes (#2847) 2023-09-30 06:43:36 -05:00
S5NC
4e3576ae48 Simplify SX126x variant configuration (#2813)
* Update SX126xInterface.cpp

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update SX126xInterface.cpp

* Update SX126xInterface.cpp

* Update variant.h

* Update variant.h

* trunk fmt

* trunk fmt

* Update variant.h

* trunk fmt

* trunk fmt

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update pins_arduino.h

* Update pins_arduino.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* trunk fmt

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* trunk fmt

* trunk fmt

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

Specify behavior

* Update variant.h

Maintain behavior

* trunk fmt

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-09-27 16:01:40 -05:00
Tavis
98290e5d7b Re issue: #2496 Populate the position log entries from PositionModule with data fields (#2839)
* Populate the position log entries with data fields

includes datafields with no data as 0

* trunk check formatted.

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-09-27 16:00:56 -05:00
Ben Meadors
ad529924f1 Code duplication cleanup for smart position logic (#2840) 2023-09-27 10:32:35 -05:00
github-actions[bot]
07d51a2ca4 [create-pull-request] automated change (#2837) 2023-09-26 14:54:35 -05:00
github-actions[bot]
47301a5ac0 [create-pull-request] automated change (#2836)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-09-26 11:11:54 -05:00
Ben Meadors
0d023ea215 Revert "Fix compression (#2806) (#2819)" (#2835)
This reverts commit cdac643749.
2023-09-26 07:02:06 -05:00
Ben Meadors
b5e952db24 No more goober traffic on public mqtt (#2831)
* No more goober traffic on public mqtt

* Oops
2023-09-26 06:19:17 -05:00
GUVWAF
a1c433748a RP2040: Add SerialModule support (#2830)
* Support for SerialModule on RP2040

* Remove one !defined too many

* Increase serial RX_BUFFER: more reliable for long packets
Even results into an error for ESP32

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-09-26 05:45:34 -05:00
Jonathan Bennett
04b2ab82dc Add GPS pin definitions missed in revamp (#2834) 2023-09-26 05:44:08 -05:00
github-actions[bot]
e96ba7cbcf [create-pull-request] automated change (#2827)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-09-25 06:31:22 -05:00
Andre K
61f6fb22c5 move STATE_SEND_METADATA to beginning of wantConfig (#2820)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-09-24 07:22:54 -05:00
github-actions[bot]
db7b77c76e [create-pull-request] automated change (#2823)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-09-24 07:01:46 -05:00
Andre K
350090ec0d remove residual code for mesh_sds_timeout_secs (#2821)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-09-24 06:49:35 -05:00
GUVWAF
cdac643749 Fix compression (#2806) (#2819)
* Fix compression: encode to bytes after `decoded` is modified

* Change payload size to decompressed length

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-09-24 06:49:21 -05:00
Jonathan Bennett
1a2c7f00e1 Gps cleanup and powersave (#2807)
* Refactor GPS to not probe if pins not defined

* Use Named Constructor to clean up code

* Move doGPSPowerSave to GPS class

* Make sure to set GPS awake on triple-click

* Cleanup and remove dead code

* Rename GPS_PIN_WAKE to GPS_PIN_STANDBY

* Actually put GPS to sleep between fixes

* add GPS_POWER_TOGGLE for heltec-tracker and t-deck

* Change GPS_THREAD_INTERVAL to 200 ms

* More dead code, compiler warnings, and add returns

* Add Number of sats to log output

* Add pgs enable and triple-click config

* Track average GPS fix time to judge low-power time

* Feed PositionModule on GPS fix

* Don't turn off the 3v3_s line on RAK4631
when the rotary is present.

* Add GPS power standbyOnly option

* Delay setting time currentQuality
to avoid strange log message.

* Typos, comments, and remove unused variable

* Short-circuit the setAwake logic on GPS disable

* heltec-tracker 0.3 GPS power saving

* set en_gpio to defined state

* Fix fixed_position logic with GPS disabled

* Don't process GPS serial when not isAwake

* Add quirk for Heltec Tracker GPS powersave

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: mverch67 <manuel.verch@gmx.de>
Co-authored-by: Manuel <71137295+mverch67@users.noreply.github.com>
2023-09-23 23:45:35 -05:00
Jonathan Bennett
7eff5e7bcb Fix for Pi Pico hang (#2817)
* Fix for Pi Pico hang

* Pi Pico fix part 2: Electric Boogaloo
2023-09-20 19:34:45 -05:00
Jonathan Bennett
17207681ef Remove GPS pins from devices lacking built-in GPS (#2812) 2023-09-19 10:55:14 -05:00
Thomas Göttgens
94f7c7e472 Merge pull request #2814 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2023-09-19 12:46:26 +02:00
caveman99
0a12d67d19 [create-pull-request] automated change 2023-09-19 10:45:28 +00:00
Thomas Göttgens
3175a3d630 Merge pull request #2811 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2023-09-19 10:48:41 +02:00
thebentern
4e9bf75340 [create-pull-request] automated change 2023-09-18 19:49:42 +00:00
github-actions[bot]
e8970ad66b [create-pull-request] automated change (#2810)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-09-18 13:26:09 -05:00
code8buster
f737ee59ec Deny maxhops to anyone who sets >7 (#2808)
* Deny maxhops to anyone who sets >7

* Use reliable hop count instead of 3
2023-09-18 12:58:09 -05:00
Ric In New Mexico
6d211815d9 Temp fix for S3 bluetooth (#2809)
Need to roll back espressif to v6.3.2
2023-09-18 14:26:19 +02:00
Manuel
1bae926576 fix: nodenum 4 (#2798)
* tryfix: nodenum 4

* trunk fmt

* rename vars and fix brackets

* purge invalid db entries

* trunk fmt
2023-09-18 06:16:37 -05:00
Thomas Göttgens
a1514b8b64 Enable (new) ADC and GPS capability. (#2792)
* Enable (new) ADC and GPS capability.
* Make Picomputer a canon device and define ADC for new board revision
2023-09-18 11:38:33 +02:00
Jonathan Bennett
8b82ae6fe3 refactor and avoid needless probe (#2799)
* Use UINT32_MAX to indicate no configured GPS

* Refactor GPS to not probe if pins not defined

* Minor cleanups related to rework

* Use Named Constructor to clean up code

* Actually disable the GPS thread

* Don't actually disable the GPS thread

* Move doGPSPowerSave to GPS class

* Make sure to set GPS awake on triple-click

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-09-16 23:10:10 -05:00
Ric In New Mexico
822c150e0d Fixing typo in src/mesh/mesh-pb-constants.cpp logging (#2800)
* Update variant.h

Add second i2c channel on external connector for Station G1

* Create trunk-check.yml

* Fix typo in logging

Corrected typo in pb_msgdesc logging for packets failing to be decoded.

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-09-16 15:24:59 -05:00
github-actions[bot]
0731902744 [create-pull-request] automated change (#2791)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-09-12 18:00:29 -05:00
github-actions[bot]
b53cb38a09 [create-pull-request] automated change (#2790)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-09-12 16:50:52 -05:00
Jonathan Bennett
b02dd0e964 Move partial GPS initialization earlier in boot (#2788)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-09-12 16:46:46 -05:00
Ben Meadors
c608f0ba81 Fix time=0 bug for fixed_position nodes (#2789) 2023-09-12 15:54:50 -05:00
Jonathan Bennett
e1839e33f2 Lazy probe of GPS (#2781)
* First attempt at lazy config of GPS

* More GPS rework
Break GPS init into smaller, interruptable steps
Move more GPS commands into ubx.h
Combine Setup functions

* Move the rest of UBX messages to ubs.h
2023-09-10 22:21:14 -05:00
Manuel
d6d51bc3f4 T-Deck/T-Watch: enhancements/fixes (#2786)
* T-Deck: enhancements/fixes

* trunk fmt

* T-Watch board update

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-09-10 06:54:25 -05:00
github-actions[bot]
44a77a10e1 [create-pull-request] automated change (#2785)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-09-10 06:34:48 -05:00
Ben Meadors
8255128eae Trunk finally spilled the beans about what it's upset about 2023-09-09 19:40:57 -05:00
Ric In New Mexico
d7a98519f4 Update variant.h (#2778)
* Update variant.h

Add second i2c channel on external connector for Station G1

* Create trunk-check.yml

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-09-09 19:37:35 -05:00
github-actions[bot]
e256520336 [create-pull-request] automated change (#2782)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-09-08 14:34:58 -05:00
Ben Meadors
fcf798df98 Experiment with moving gps init (#2780)
* Move it move it

* Moving to the end of the main setup method

* NimBLE version
2023-09-07 16:01:35 -05:00
Ben Meadors
dcdf9b64de Ambient lighting (#2779)
* This was already defined and throwing a ton of warnings

* Ambient lighting module feature

* Use local instance type
2023-09-07 12:24:47 -05:00
Jonathan Bennett
fd563e41f1 Add ubx-cfg-rxm and cfg-pm2 for ublock 6 powersave (#2777) 2023-09-07 12:24:21 -05:00
Jonathan Bennett
0fa3685161 Fix crash in GPS setup when GPS is disabled 2023-09-06 12:38:58 -05:00
code8buster
899f9dd7bf Merge pull request #2775 from GUVWAF/disabledNeighbor
Only update neighbors when module is enabled
2023-09-05 23:43:09 +00:00
GUVWAF
9af4ecf48f Remove unnecessary line when disabled 2023-09-05 21:42:39 +02:00
GUVWAF
cfb6a1394c Only update neighbors when module is enabled 2023-09-05 19:56:42 +02:00
code8buster
1254031f7d Merge pull request #2772 from meshtastic/ubx-pmreq
UBX-RXM-PMREQ soft-off implemented
2023-09-05 17:15:12 +00:00
code8buster
c91e306659 Move packet scratch declaration to header 2023-09-05 11:59:34 -04:00
code8buster
4ff343b20f no byte... just 8 unsigned bits please 2023-09-05 00:32:53 -04:00
code8buster
134fc75b67 UBX-RXM-PMREQ soft-off implemented 2023-09-05 00:26:42 -04:00
Ben Meadors
fb23e479ac Update ESP32 platform (#2770) 2023-09-04 20:20:20 -05:00
github-actions[bot]
5a61695016 [create-pull-request] automated change (#2769)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-09-04 19:45:46 -05:00
113 changed files with 1848 additions and 1554 deletions

22
.github/workflows/trunk-check.yml vendored Normal file
View File

@@ -0,0 +1,22 @@
name: Pull Request
on: [pull_request]
concurrency:
group: ${{ github.head_ref || github.run_id }}
cancel-in-progress: true
permissions: read-all
jobs:
trunk_check:
name: Trunk Check Runner
runs-on: ubuntu-latest
permissions:
checks: write # For trunk to post annotations
contents: read # For repo checkout
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Trunk Check
uses: trunk-io/trunk-action@v1

View File

@@ -1,7 +1,7 @@
; Common settings for ESP targes, mixin with extends = esp32_base
[esp32_base]
extends = arduino_base
platform = platformio/espressif32@^6.3.2
platform = platformio/espressif32@6.3.2 # This is a temporary fix to the S3-based devices bluetooth issues until we can determine what within ESP-IDF changed and can develop a suitable patch.
build_src_filter =
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2040> -<mesh/eth/>
@@ -38,7 +38,7 @@ lib_deps =
${networking_base.lib_deps}
${environmental_base.lib_deps}
https://github.com/meshtastic/esp32_https_server.git#23665b3adc080a311dcbb586ed5941b5f94d6ea2
h2zero/NimBLE-Arduino@^1.4.0
h2zero/NimBLE-Arduino@^1.4.1
jgromes/RadioLib@^6.1.0
https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6
https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f
@@ -57,4 +57,4 @@ lib_ignore =
; customize the partition table
; http://docs.platformio.org/en/latest/platforms/espressif32.html#partition-tables
board_build.partitions = partition-table.csv
board_build.partitions = partition-table.csv

View File

@@ -1,7 +1,8 @@
{
"build": {
"arduino": {
"ldscript": "esp32s3_out.ld"
"ldscript": "esp32s3_out.ld",
"memory_type": "qio_opi"
},
"core": "esp32",
"extra_flags": [
@@ -13,7 +14,7 @@
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "dio",
"flash_mode": "qio",
"hwids": [["0x303A", "0x1001"]],
"mcu": "esp32s3",
"variant": "t-deck"

View File

@@ -1,7 +1,8 @@
{
"build": {
"arduino": {
"ldscript": "esp32s3_out.ld"
"ldscript": "esp32s3_out.ld",
"memory_type": "qio_opi"
},
"core": "esp32",
"extra_flags": [
@@ -14,7 +15,7 @@
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "dio",
"flash_mode": "qio",
"hwids": [["0x303A", "0x1001"]],
"mcu": "esp32s3",
"variant": "t-watch-s3"
@@ -31,8 +32,9 @@
"maximum_size": 8388608,
"require_upload_port": true,
"use_1200bps_touch": true,
"wait_for_upload_port": true
"wait_for_upload_port": true,
"speed": 921600
},
"url": "http://www.lilygo.cn/",
"url": "https://www.lilygo.cc/en-pl/products/t-watch-s3",
"vendor": "LilyGo"
}

View File

@@ -70,7 +70,7 @@ lib_deps =
https://github.com/meshtastic/esp8266-oled-ssd1306.git#b38094e03dfa964fbc0e799bc374e91a605c1223 ; ESP8266_SSD1306
https://github.com/mathertel/OneButton#2.1.0 ; OneButton library for non-blocking button debounce
https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159
https://github.com/meshtastic/TinyGPSPlus.git#127ad674ef85f0201cb68a065879653ed94792c4
https://github.com/meshtastic/TinyGPSPlus.git#076e8d2c8fb702d9be5b08c55b93ff76f8af7e61
https://github.com/meshtastic/ArduinoThread.git#72921ac222eed6f526ba1682023cee290d9aa1b3
nanopb/Nanopb@^0.4.7
erriez/ErriezCRC32@^1.0.1

View File

@@ -0,0 +1,75 @@
#include "configuration.h"
#ifdef HAS_NCP5623
#include <graphics/RAKled.h>
NCP5623 rgb;
#endif
namespace concurrency
{
class AmbientLightingThread : public concurrency::OSThread
{
public:
AmbientLightingThread(ScanI2C::DeviceType type) : OSThread("AmbientLightingThread")
{
// Uncomment to test module
// moduleConfig.ambient_lighting.led_state = true;
// moduleConfig.ambient_lighting.current = 10;
// // Default to a color based on our node number
// moduleConfig.ambient_lighting.red = (myNodeInfo.my_node_num & 0xFF0000) >> 16;
// moduleConfig.ambient_lighting.green = (myNodeInfo.my_node_num & 0x00FF00) >> 8;
// moduleConfig.ambient_lighting.blue = myNodeInfo.my_node_num & 0x0000FF;
#ifdef HAS_NCP5623
_type = type;
if (_type == ScanI2C::DeviceType::NONE) {
LOG_DEBUG("AmbientLightingThread disabling due to no RGB leds found on I2C bus\n");
disable();
return;
}
if (!moduleConfig.ambient_lighting.led_state) {
LOG_DEBUG("AmbientLightingThread disabling due to moduleConfig.ambient_lighting.led_state OFF\n");
disable();
return;
}
LOG_DEBUG("AmbientLightingThread initializing\n");
if (_type == ScanI2C::NCP5623) {
rgb.begin();
setLighting();
}
#endif
}
protected:
int32_t runOnce() override
{
#ifdef HAS_NCP5623
if (_type == ScanI2C::NCP5623 && moduleConfig.ambient_lighting.led_state) {
setLighting();
return 30000; // 30 seconds to reset from any animations that may have been running from Ext. Notification
} else {
return disable();
}
#else
return disable();
#endif
}
private:
ScanI2C::DeviceType _type = ScanI2C::DeviceType::NONE;
void setLighting()
{
#ifdef HAS_NCP5623
rgb.setCurrent(moduleConfig.ambient_lighting.current);
rgb.setRed(moduleConfig.ambient_lighting.red);
rgb.setGreen(moduleConfig.ambient_lighting.green);
rgb.setBlue(moduleConfig.ambient_lighting.blue);
LOG_DEBUG("Initializing Ambient lighting w/ current=%d, red=%d, green=%d, blue=%d\n",
moduleConfig.ambient_lighting.current, moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green,
moduleConfig.ambient_lighting.blue);
#endif
}
};
} // namespace concurrency

View File

@@ -164,15 +164,17 @@ class ButtonThread : public concurrency::OSThread
static void userButtonMultiPressed()
{
#if defined(GPS_POWER_TOGGLE)
if (config.position.gps_enabled) {
LOG_DEBUG("Flag set to false for gps power\n");
} else {
LOG_DEBUG("Flag set to true to restore power\n");
if (!config.device.disable_triple_click && (gps != nullptr)) {
config.position.gps_enabled = !(config.position.gps_enabled);
if (config.position.gps_enabled) {
LOG_DEBUG("Flag set to true to restore power\n");
gps->enable();
} else {
LOG_DEBUG("Flag set to false for gps power\n");
gps->disable();
}
}
config.position.gps_enabled = !(config.position.gps_enabled);
doGPSpowersave(config.position.gps_enabled);
#endif
}
static void userButtonPressedLongStart()

View File

@@ -414,7 +414,7 @@ void Power::shutdown()
#ifdef PIN_LED3
ledOff(PIN_LED2);
#endif
doDeepSleep(DELAY_FOREVER);
doDeepSleep(DELAY_FOREVER, false);
#endif
}

View File

@@ -8,7 +8,6 @@
* actions to be taken upon entering or exiting each state.
*/
#include "PowerFSM.h"
#include "GPS.h"
#include "MeshService.h"
#include "NodeDB.h"
#include "configuration.h"
@@ -46,7 +45,7 @@ static void sdsEnter()
{
LOG_DEBUG("Enter state: SDS\n");
// FIXME - make sure GPS and LORA radio are off first - because we want close to zero current draw
doDeepSleep(getConfiguredOrDefaultMs(config.power.sds_secs));
doDeepSleep(getConfiguredOrDefaultMs(config.power.sds_secs), false);
}
extern Power *power;
@@ -137,9 +136,6 @@ static void lsIdle()
static void lsExit()
{
LOG_INFO("Exit state: LS\n");
// setGPSPower(true); // restore GPS power
if (gps)
gps->forceWake(true);
}
static void nbEnter()
@@ -249,6 +245,8 @@ Fsm powerFSM(&stateBOOT);
void PowerFSM_setup()
{
bool isRouter = (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER ? 1 : 0);
bool isTrackerOrSensor = config.device.role == meshtastic_Config_DeviceConfig_Role_TRACKER ||
config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR;
bool hasPower = isPowered();
LOG_INFO("PowerFSM init, USB power=%d\n", hasPower ? 1 : 0);
@@ -352,12 +350,12 @@ void PowerFSM_setup()
getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs), NULL,
"Screen-on timeout");
// We never enter light-sleep or NB states on NRF52 (because the CPU uses so little power normally)
#ifdef ARCH_ESP32
State *lowPowerState = &stateLS;
// We never enter light-sleep or NB states on NRF52 (because the CPU uses so little power normally)
// See: https://github.com/meshtastic/firmware/issues/1071
if (isRouter || config.power.is_power_saving) {
// Don't add power saving transitions if we are a power saving tracker or sensor. Sleep will be initiatiated through the
// modules
if ((isRouter || config.power.is_power_saving) && !isTrackerOrSensor) {
powerFSM.add_timed_transition(&stateNB, &stateLS,
getConfiguredOrDefaultMs(config.power.min_wake_secs, default_min_wake_secs), NULL,
"Min wake timeout");
@@ -365,10 +363,6 @@ void PowerFSM_setup()
getConfiguredOrDefaultMs(config.power.wait_bluetooth_secs, default_wait_bluetooth_secs),
NULL, "Bluetooth timeout");
}
if (config.power.sds_secs != UINT32_MAX)
powerFSM.add_timed_transition(lowPowerState, &stateSDS, getConfiguredOrDefaultMs(config.power.sds_secs), NULL,
"mesh timeout");
#endif
powerFSM.run_machine(); // run one iteration of the state machine, so we run our on enter tasks for the initial DARK state

View File

@@ -53,7 +53,7 @@ class OSThread : public Thread
static void setup();
int32_t disable();
virtual int32_t disable();
/**
* Wait a specified number msecs starting from the current time (rather than the last time we were run)
@@ -67,6 +67,7 @@ class OSThread : public Thread
* Returns desired period for next invocation (or RUN_SAME for no change)
*/
virtual int32_t runOnce() = 0;
bool sleepOnNextExecution = false;
// Do not override this
virtual void run();
@@ -87,4 +88,4 @@ extern bool hasBeenSetup;
void assertIsSetup();
} // namespace concurrency
} // namespace concurrency

View File

@@ -145,7 +145,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define GPS_BAUDRATE 9600
#ifndef GPS_THREAD_INTERVAL
#define GPS_THREAD_INTERVAL 100
#define GPS_THREAD_INTERVAL 200
#endif
// convert 24-bit color to 16-bit (56K)

File diff suppressed because it is too large Load Diff

View File

@@ -2,7 +2,16 @@
#include "GPSStatus.h"
#include "Observer.h"
#include "TinyGPS++.h"
#include "concurrency/OSThread.h"
#include "input/RotaryEncoderInterruptImpl1.h"
#include "input/UpDownInterruptImpl1.h"
#include "modules/PositionModule.h"
// Allow defining the polarity of the ENABLE output. default is active high
#ifndef GPS_EN_ACTIVE
#define GPS_EN_ACTIVE 1
#endif
struct uBloxGnssModelInfo {
char swVersion[30];
@@ -35,8 +44,29 @@ const char *getDOPString(uint32_t dop);
*/
class GPS : private concurrency::OSThread
{
TinyGPSPlus reader;
uint8_t fixQual = 0; // fix quality from GPGGA
uint32_t lastChecksumFailCount = 0;
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
// (20210908) TinyGps++ can only read the GPGSA "FIX TYPE" field
// via optional feature "custom fields", currently disabled (bug #525)
TinyGPSCustom gsafixtype; // custom extract fix type from GPGSA
TinyGPSCustom gsapdop; // custom extract PDOP from GPGSA
uint8_t fixType = 0; // fix type from GPGSA
#endif
private:
uint32_t lastWakeStartMsec = 0, lastSleepStartMsec = 0, lastWhileActiveMsec = 0;
uint32_t lastWakeStartMsec = 0, lastSleepStartMsec = 0;
const int serialSpeeds[6] = {9600, 4800, 38400, 57600, 115200, 9600};
uint32_t rx_gpio = 0;
uint32_t tx_gpio = 0;
uint32_t en_gpio = 0;
int32_t averageLockTime = 0;
uint32_t GPSCycles = 0;
int speedSelect = 0;
int probeTries = 2;
/**
* hasValidLocation - indicates that the position variables contain a complete
@@ -46,15 +76,17 @@ class GPS : private concurrency::OSThread
bool isAwake = false; // true if we want a location right now
bool wakeAllowed = true; // false if gps must be forced to sleep regardless of what time it is
bool isInPowersave = false;
bool shouldPublish = false; // If we've changed GPS state, this will force a publish the next loop()
bool hasGPS = false; // Do we have a GPS we are talking to
bool GPSInitFinished = false; // Init thread finished?
bool GPSInitStarted = false; // Init thread finished?
uint8_t numSatellites = 0;
CallbackObserver<GPS, void *> notifySleepObserver = CallbackObserver<GPS, void *>(this, &GPS::prepareSleep);
CallbackObserver<GPS, void *> notifyDeepSleepObserver = CallbackObserver<GPS, void *>(this, &GPS::prepareDeepSleep);
CallbackObserver<GPS, void *> notifyGPSSleepObserver = CallbackObserver<GPS, void *>(this, &GPS::prepareDeepSleep);
@@ -62,6 +94,24 @@ class GPS : private concurrency::OSThread
/** If !NULL we will use this serial port to construct our GPS */
static HardwareSerial *_serial_gps;
static uint8_t _message_PMREQ[];
static const uint8_t _message_CFG_RXM_PSM[];
static const uint8_t _message_CFG_RXM_ECO[];
static const uint8_t _message_CFG_PM2[];
static const uint8_t _message_GNSS_7[];
static const uint8_t _message_GNSS[];
static const uint8_t _message_JAM[];
static const uint8_t _message_NAVX5[];
static const uint8_t _message_1HZ[];
static const uint8_t _message_GGL[];
static const uint8_t _message_GSA[];
static const uint8_t _message_GSV[];
static const uint8_t _message_VTG[];
static const uint8_t _message_RMC[];
static const uint8_t _message_GGA[];
static const uint8_t _message_PMS[];
static const uint8_t _message_SAVE[];
meshtastic_Position p = meshtastic_Position_init_default;
GPS() : concurrency::OSThread("GPS") {}
@@ -76,6 +126,14 @@ class GPS : private concurrency::OSThread
*/
virtual bool setup();
// re-enable the thread
void enable();
// Disable the thread
int32_t disable() override;
void setGPSPower(bool on, bool standbyOnly, uint32_t sleepTime);
/// Returns true if we have acquired GPS lock.
virtual bool hasLock();
@@ -87,71 +145,20 @@ class GPS : private concurrency::OSThread
bool isPowerSaving() const { return !config.position.gps_enabled; }
/**
* Restart our lock attempt - try to get and broadcast a GPS reading ASAP
* called after the CPU wakes from light-sleep state
*
* Or set to false, to disallow any sort of waking
* */
void forceWake(bool on);
// Some GPS modules (ublock) require factory reset
virtual bool factoryReset() { return true; }
// Empty the input buffer as quickly as possible
void clearBuffer();
protected:
/// Do gps chipset specific init, return true for success
virtual bool setupGPS();
// Create a ublox packet for editing in memory
uint8_t makeUBXPacket(uint8_t class_id, uint8_t msg_id, uint8_t payload_size, const uint8_t *msg);
/// If possible force the GPS into sleep/low power mode
virtual void sleep();
// scratch space for creating ublox packets
uint8_t UBXscratch[250] = {0};
/// wake the GPS into normal operation mode
virtual void wake();
int rebootsSeen = 0;
/** Subclasses should look for serial rx characters here and feed it to their GPS parser
*
* Return true if we received a valid message from the GPS
*/
virtual bool whileIdle() = 0;
/** Idle processing while GPS is looking for lock, called once per secondish */
virtual void whileActive() {}
/**
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
* Override this method to check for new locations
*
* @return true if we've acquired a time
*/
virtual bool lookForTime() = 0;
/**
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
* Override this method to check for new locations
*
* @return true if we've acquired a new location
*/
virtual bool lookForLocation() = 0;
/// Record that we have a GPS
void setConnected();
void setNumSatellites(uint8_t n);
private:
/// Prepare the GPS for the cpu entering deep or light sleep, expect to be gone for at least 100s of msecs
/// always returns 0 to indicate okay to sleep
int prepareSleep(void *unused);
/// Prepare the GPS for the cpu entering deep sleep, expect to be gone for at least 100s of msecs
/// always returns 0 to indicate okay to sleep
int prepareDeepSleep(void *unused);
// Calculate checksum
void UBXChecksum(byte *message, size_t length);
int getACK(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t requestedID, uint32_t waitMillis);
GPS_RESPONSE getACK(uint8_t c, uint8_t i, uint32_t waitMillis);
GPS_RESPONSE getACK(const char *message, uint32_t waitMillis);
/**
* Switch the GPS into a mode where we are actively looking for a lock, or alternatively switch GPS into a low power mode
@@ -159,6 +166,59 @@ class GPS : private concurrency::OSThread
* calls sleep/wake
*/
void setAwake(bool on);
virtual bool factoryReset();
// Creates an instance of the GPS class.
// Returns the new instance or null if the GPS is not present.
static GPS *createGps();
protected:
/**
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
* Override this method to check for new locations
*
* @return true if we've acquired a time
*/
/**
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
* Override this method to check for new locations
*
* @return true if we've acquired a new location
*/
/// Record that we have a GPS
void setConnected();
/** Subclasses should look for serial rx characters here and feed it to their GPS parser
*
* Return true if we received a valid message from the GPS
*/
virtual bool whileIdle();
/**
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
* Override this method to check for new locations
*
* @return true if we've acquired a time
*/
virtual bool lookForTime();
/**
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
* Override this method to check for new locations
*
* @return true if we've acquired a new location
*/
virtual bool lookForLocation();
private:
/// Prepare the GPS for the cpu entering deep sleep, expect to be gone for at least 100s of msecs
/// always returns 0 to indicate okay to sleep
int prepareDeepSleep(void *unused);
// Calculate checksum
void UBXChecksum(uint8_t *message, size_t length);
/** Get how long we should stay looking for each aquisition
*/
@@ -179,9 +239,6 @@ class GPS : private concurrency::OSThread
String getNMEA();
GnssModel_t probe(int serialSpeed);
int getACK(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t requestedID, uint32_t waitMillis);
GPS_RESPONSE getACK(uint8_t c, uint8_t i, uint32_t waitMillis);
GPS_RESPONSE getACK(const char *message, uint32_t waitMillis);
// delay counter to allow more sats before fixed position stops GPS thread
uint8_t fixeddelayCtr = 0;
@@ -189,8 +246,4 @@ class GPS : private concurrency::OSThread
GnssModel_t gnssModel = GNSS_MODEL_UNKNOWN;
};
// Creates an instance of the GPS class.
// Returns the new instance or null if the GPS is not present.
GPS *createGps();
extern GPS *gps;

View File

@@ -1,272 +0,0 @@
#include "NMEAGPS.h"
#include "RTC.h"
#include "configuration.h"
#include <TinyGPS++.h>
// GPS solutions older than this will be rejected - see TinyGPSDatum::age()
#define GPS_SOL_EXPIRY_MS 5000 // in millis. give 1 second time to combine different sentences. NMEA Frequency isn't higher anyway
#define NMEA_MSG_GXGSA "GNGSA" // GSA message (GPGSA, GNGSA etc)
static int32_t toDegInt(RawDegrees d)
{
int32_t degMult = 10000000; // 1e7
int32_t r = d.deg * degMult + d.billionths / 100;
if (d.negative)
r *= -1;
return r;
}
bool NMEAGPS::factoryReset()
{
#ifdef PIN_GPS_REINIT
// The L76K GNSS on the T-Echo requires the RESET pin to be pulled LOW
digitalWrite(PIN_GPS_REINIT, 0);
pinMode(PIN_GPS_REINIT, OUTPUT);
delay(150); // The L76K datasheet calls for at least 100MS delay
digitalWrite(PIN_GPS_REINIT, 1);
#endif
// send the UBLOX Factory Reset Command regardless of detect state, something is very wrong, just assume it's UBLOX.
// Factory Reset
byte _message_reset[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF, 0xFB, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x17, 0x2B, 0x7E};
_serial_gps->write(_message_reset, sizeof(_message_reset));
delay(1000);
return true;
}
bool NMEAGPS::setupGPS()
{
GPS::setupGPS();
#ifdef PIN_GPS_PPS
// pulse per second
// FIXME - move into shared GPS code
pinMode(PIN_GPS_PPS, INPUT);
#endif
// Currently disabled per issue #525 (TinyGPS++ crash bug)
// when fixed upstream, can be un-disabled to enable 3D FixType and PDOP
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
// see NMEAGPS.h
gsafixtype.begin(reader, NMEA_MSG_GXGSA, 2);
gsapdop.begin(reader, NMEA_MSG_GXGSA, 15);
LOG_DEBUG("Using " NMEA_MSG_GXGSA " for 3DFIX and PDOP\n");
#else
LOG_DEBUG("GxGSA NOT available\n");
#endif
return true;
}
/**
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
* Override this method to check for new locations
*
* @return true if we've acquired a new location
*/
bool NMEAGPS::lookForTime()
{
auto ti = reader.time;
auto d = reader.date;
if (ti.isValid() && d.isValid()) { // Note: we don't check for updated, because we'll only be called if needed
/* Convert to unix time
The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of seconds that have elapsed since January 1, 1970
(midnight UTC/GMT), not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z).
*/
struct tm t;
t.tm_sec = ti.second();
t.tm_min = ti.minute();
t.tm_hour = ti.hour();
t.tm_mday = d.day();
t.tm_mon = d.month() - 1;
t.tm_year = d.year() - 1900;
t.tm_isdst = false;
if (t.tm_mon > -1) {
LOG_DEBUG("NMEA GPS time %02d-%02d-%02d %02d:%02d:%02d\n", d.year(), d.month(), t.tm_mday, t.tm_hour, t.tm_min,
t.tm_sec);
perhapsSetRTC(RTCQualityGPS, t);
return true;
} else
return false;
} else
return false;
}
/**
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
* Override this method to check for new locations
*
* @return true if we've acquired a new location
*/
bool NMEAGPS::lookForLocation()
{
// By default, TinyGPS++ does not parse GPGSA lines, which give us
// the 2D/3D fixType (see NMEAGPS.h)
// At a minimum, use the fixQuality indicator in GPGGA (FIXME?)
fixQual = reader.fixQuality();
#ifndef TINYGPS_OPTION_NO_STATISTICS
if (reader.failedChecksum() > lastChecksumFailCount) {
LOG_WARN("Warning, %u new GPS checksum failures, for a total of %u.\n", reader.failedChecksum() - lastChecksumFailCount,
reader.failedChecksum());
lastChecksumFailCount = reader.failedChecksum();
}
#endif
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
fixType = atoi(gsafixtype.value()); // will set to zero if no data
// LOG_DEBUG("FIX QUAL=%d, TYPE=%d\n", fixQual, fixType);
#endif
// check if GPS has an acceptable lock
if (!hasLock())
return false;
#ifdef GPS_EXTRAVERBOSE
LOG_DEBUG("AGE: LOC=%d FIX=%d DATE=%d TIME=%d\n", reader.location.age(),
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
gsafixtype.age(),
#else
0,
#endif
reader.date.age(), reader.time.age());
#endif // GPS_EXTRAVERBOSE
// check if a complete GPS solution set is available for reading
// tinyGPSDatum::age() also includes isValid() test
// FIXME
if (!((reader.location.age() < GPS_SOL_EXPIRY_MS) &&
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
(gsafixtype.age() < GPS_SOL_EXPIRY_MS) &&
#endif
(reader.time.age() < GPS_SOL_EXPIRY_MS) && (reader.date.age() < GPS_SOL_EXPIRY_MS))) {
LOG_WARN("SOME data is TOO OLD: LOC %u, TIME %u, DATE %u\n", reader.location.age(), reader.time.age(), reader.date.age());
return false;
}
// Is this a new point or are we re-reading the previous one?
if (!reader.location.isUpdated())
return false;
// We know the solution is fresh and valid, so just read the data
auto loc = reader.location.value();
// Bail out EARLY to avoid overwriting previous good data (like #857)
if (toDegInt(loc.lat) > 900000000) {
#ifdef GPS_EXTRAVERBOSE
LOG_DEBUG("Bail out EARLY on LAT %i\n", toDegInt(loc.lat));
#endif
return false;
}
if (toDegInt(loc.lng) > 1800000000) {
#ifdef GPS_EXTRAVERBOSE
LOG_DEBUG("Bail out EARLY on LNG %i\n", toDegInt(loc.lng));
#endif
return false;
}
p.location_source = meshtastic_Position_LocSource_LOC_INTERNAL;
// Dilution of precision (an accuracy metric) is reported in 10^2 units, so we need to scale down when we use it
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
p.HDOP = reader.hdop.value();
p.PDOP = TinyGPSPlus::parseDecimal(gsapdop.value());
// LOG_DEBUG("PDOP=%d, HDOP=%d\n", p.PDOP, p.HDOP);
#else
// FIXME! naive PDOP emulation (assumes VDOP==HDOP)
// correct formula is PDOP = SQRT(HDOP^2 + VDOP^2)
p.HDOP = reader.hdop.value();
p.PDOP = 1.41 * reader.hdop.value();
#endif
// Discard incomplete or erroneous readings
if (reader.hdop.value() == 0) {
LOG_WARN("BOGUS hdop.value() REJECTED: %d\n", reader.hdop.value());
return false;
}
p.latitude_i = toDegInt(loc.lat);
p.longitude_i = toDegInt(loc.lng);
p.altitude_geoidal_separation = reader.geoidHeight.meters();
p.altitude_hae = reader.altitude.meters() + p.altitude_geoidal_separation;
p.altitude = reader.altitude.meters();
p.fix_quality = fixQual;
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
p.fix_type = fixType;
#endif
// positional timestamp
struct tm t;
t.tm_sec = reader.time.second();
t.tm_min = reader.time.minute();
t.tm_hour = reader.time.hour();
t.tm_mday = reader.date.day();
t.tm_mon = reader.date.month() - 1;
t.tm_year = reader.date.year() - 1900;
t.tm_isdst = false;
p.timestamp = mktime(&t);
// Nice to have, if available
if (reader.satellites.isUpdated()) {
p.sats_in_view = reader.satellites.value();
}
if (reader.course.isUpdated() && reader.course.isValid()) {
if (reader.course.value() < 36000) { // sanity check
p.ground_track =
reader.course.value() * 1e3; // Scale the heading (in degrees * 10^-2) to match the expected degrees * 10^-5
} else {
LOG_WARN("BOGUS course.value() REJECTED: %d\n", reader.course.value());
}
}
if (reader.speed.isUpdated() && reader.speed.isValid()) {
p.ground_speed = reader.speed.kmph();
}
return true;
}
bool NMEAGPS::hasLock()
{
// Using GPGGA fix quality indicator
if (fixQual >= 1 && fixQual <= 5) {
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
// Use GPGSA fix type 2D/3D (better) if available
if (fixType == 3 || fixType == 0) // zero means "no data received"
#endif
return true;
}
return false;
}
bool NMEAGPS::hasFlow()
{
return reader.passedChecksum() > 0;
}
bool NMEAGPS::whileIdle()
{
bool isValid = false;
#ifdef SERIAL_BUFFER_SIZE
if (_serial_gps->available() >= SERIAL_BUFFER_SIZE - 1) {
LOG_WARN("GPS Buffer full with %u bytes waiting. Flushing to avoid corruption.\n", _serial_gps->available());
clearBuffer();
}
#endif
// if (_serial_gps->available() > 0)
// LOG_DEBUG("GPS Bytes Waiting: %u\n", _serial_gps->available());
// First consume any chars that have piled up at the receiver
while (_serial_gps->available() > 0) {
int c = _serial_gps->read();
// LOG_DEBUG("%c", c);
isValid |= reader.encode(c);
}
return isValid;
}

View File

@@ -1,57 +0,0 @@
#pragma once
#include "GPS.h"
#include "Observer.h"
#include "TinyGPS++.h"
/**
* A gps class thatreads from a NMEA GPS stream (and FIXME - eventually keeps the gps powered down except when reading)
*
* When new data is available it will notify observers.
*/
class NMEAGPS : public GPS
{
TinyGPSPlus reader;
uint8_t fixQual = 0; // fix quality from GPGGA
uint32_t lastChecksumFailCount = 0;
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
// (20210908) TinyGps++ can only read the GPGSA "FIX TYPE" field
// via optional feature "custom fields", currently disabled (bug #525)
TinyGPSCustom gsafixtype; // custom extract fix type from GPGSA
TinyGPSCustom gsapdop; // custom extract PDOP from GPGSA
uint8_t fixType = 0; // fix type from GPGSA
#endif
public:
virtual bool setupGPS() override;
virtual bool factoryReset() override;
protected:
/** Subclasses should look for serial rx characters here and feed it to their GPS parser
*
* Return true if we received a valid message from the GPS
*/
virtual bool whileIdle() override;
/**
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
* Override this method to check for new locations
*
* @return true if we've acquired a time
*/
virtual bool lookForTime() override;
/**
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
* Override this method to check for new locations
*
* @return true if we've acquired a new location
*/
virtual bool lookForLocation() override;
virtual bool hasLock() override;
virtual bool hasFlow() override;
};

View File

@@ -103,9 +103,8 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
bool shouldSet;
if (q > currentQuality) {
currentQuality = q;
shouldSet = true;
LOG_DEBUG("Upgrading time to RTC %ld secs (quality %d)\n", tv->tv_sec, q);
LOG_DEBUG("Upgrading time to quality %d\n", q);
} else if (q == RTCQualityGPS && (now - lastSetMsec) > (12 * 60 * 60 * 1000UL)) {
// Every 12 hrs we will slam in a new GPS time, to correct for local RTC clock drift
shouldSet = true;
@@ -114,12 +113,12 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
shouldSet = false;
if (shouldSet) {
currentQuality = q;
lastSetMsec = now;
// This delta value works on all platforms
timeStartMsec = now;
zeroOffsetSecs = tv->tv_sec;
// If this platform has a setable RTC, set it
#ifdef RV3028_RTC
if (rtc_found.address == RV3028_RTC) {
@@ -209,4 +208,4 @@ uint32_t getTime()
uint32_t getValidTime(RTCQuality minQuality)
{
return (currentQuality >= minQuality) ? getTime() : 0;
}
}

192
src/gps/ubx.h Normal file
View File

@@ -0,0 +1,192 @@
uint8_t GPS::_message_PMREQ[] PROGMEM = {
0x00, 0x00, // 4 bytes duration of request task
0x00, 0x00, // (milliseconds)
0x02, 0x00, // Task flag bitfield
0x00, 0x00 // byte index 1 = sleep mode
};
const uint8_t GPS::_message_CFG_RXM_PSM[] PROGMEM = {
0x08, // Reserved
0x01 // Power save mode
};
const uint8_t GPS::_message_CFG_RXM_ECO[] PROGMEM = {
0x08, // Reserved
0x04 // eco mode
};
const uint8_t GPS::_message_CFG_PM2[] PROGMEM = {
0x01, 0x06, 0x00, 0x00, // version, Reserved
0x0E, 0x81, 0x43, 0x01, // flags
0xE8, 0x03, 0x00, 0x00, // update period 1000 ms
0x10, 0x27, 0x00, 0x00, // search period 10s
0x00, 0x00, 0x00, 0x00, // Grod offset 0
0x01, 0x00, // onTime 1 second
0x00, 0x00, // min search time 0
0x2C, 0x01, // reserved
0x00, 0x00, 0x4F, 0xC1, // reserved
0x03, 0x00, 0x87, 0x02, // reserved
0x00, 0x00, 0xFF, 0x00, // reserved
0x01, 0x00, 0xD6, 0x4D // reserved
};
const uint8_t GPS::_message_GNSS_7[] = {
0x00, // msgVer (0 for this version)
0x00, // numTrkChHw (max number of hardware channels, read only, so it's always 0)
0xff, // numTrkChUse (max number of channels to use, 0xff = max available)
0x02, // numConfigBlocks (number of GNSS systems), most modules support maximum 3 GNSS systems
// GNSS config format: gnssId, resTrkCh, maxTrkCh, reserved1, flags
0x00, 0x08, 0x10, 0x00, 0x01, 0x00, 0x00, 0x01, // GPS
0x01, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x01 // SBAS
};
// It's not critical if the module doesn't acknowledge this configuration.
// The module should operate adequately with its factory or previously saved settings.
// It appears that there is a firmware bug in some GPS modules: When an attempt is made
// to overwrite a saved state with identical values, no ACK/NAK is received, contrary to
// what is specified in the Ublox documentation.
// There is also a possibility that the module may be GPS-only.
const uint8_t GPS::_message_GNSS[] = {
0x00, // msgVer (0 for this version)
0x00, // numTrkChHw (max number of hardware channels, read only, so it's always 0)
0xff, // numTrkChUse (max number of channels to use, 0xff = max available)
0x03, // numConfigBlocks (number of GNSS systems), most modules support maximum 3 GNSS systems
// GNSS config format: gnssId, resTrkCh, maxTrkCh, reserved1, flags
0x00, 0x08, 0x10, 0x00, 0x01, 0x00, 0x01, 0x01, // GPS
0x01, 0x01, 0x03, 0x00, 0x01, 0x00, 0x01, 0x01, // SBAS
0x06, 0x08, 0x0e, 0x00, 0x01, 0x00, 0x01, 0x01 // GLONASS
};
// Enable interference resistance, because we are using LoRa, WiFi and Bluetooth on same board,
// and we need to reduce interference from them
const uint8_t GPS::_message_JAM[] = {
// bbThreshold (Broadband jamming detection threshold) is set to 0x3F (63 in decimal)
// cwThreshold (CW jamming detection threshold) is set to 0x10 (16 in decimal)
// algorithmBits (Reserved algorithm settings) is set to 0x16B156 as recommended
// enable (Enable interference detection) is set to 1 (enabled)
0x3F, 0x10, 0xB1, 0x56, // config: Interference config word
// generalBits (General settings) is set to 0x31E as recommended
// antSetting (Antenna setting, 0=unknown, 1=passive, 2=active) is set to 0 (unknown)
// ToDo: Set to 1 (passive) or 2 (active) if known, for example from UBX-MON-HW, or from board info
// enable2 (Set to 1 to scan auxiliary bands, u-blox 8 / u-blox M8 only, otherwise ignored) is set to 1
// (enabled)
0x1E, 0x03, 0x00, 0x01 // config2: Extra settings for jamming/interference monitor
};
// Configure navigation engine expert settings:
const uint8_t GPS::_message_NAVX5[] = {
0x00, 0x00, // msgVer (0 for this version)
// minMax flag = 1: apply min/max SVs settings
// minCno flag = 1: apply minimum C/N0 setting
// initial3dfix flag = 0: apply initial 3D fix settings
// aop flag = 1: apply aopCfg (useAOP flag) settings (AssistNow Autonomous)
0x1B, 0x00, // mask1 (First parameters bitmask)
// adr flag = 0: apply ADR sensor fusion on/off setting (useAdr flag)
// If firmware is not ADR/UDR, enabling this flag will fail configuration
// ToDo: check this with UBX-MON-VER
0x00, 0x00, 0x00, 0x00, // mask2 (Second parameters bitmask)
0x00, 0x00, // Reserved
0x03, // minSVs (Minimum number of satellites for navigation) = 3
0x10, // maxSVs (Maximum number of satellites for navigation) = 16
0x06, // minCNO (Minimum satellite signal level for navigation) = 6 dBHz
0x00, // Reserved
0x00, // iniFix3D (Initial fix must be 3D) = 0 (disabled)
0x00, 0x00, // Reserved
0x00, // ackAiding (Issue acknowledgements for assistance message input) = 0 (disabled)
0x00, 0x00, // Reserved
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Reserved
0x00, // Reserved
0x01, // aopCfg (AssistNow Autonomous configuration) = 1 (enabled)
0x00, 0x00, // Reserved
0x00, 0x00, // Reserved
0x00, 0x00, 0x00, 0x00, // Reserved
0x00, 0x00, 0x00, // Reserved
0x01, // useAdr (Enable/disable ADR sensor fusion) = 1 (enabled)
};
// Set GPS update rate to 1Hz
// Lowering the update rate helps to save power.
// Additionally, for some new modules like the M9/M10, an update rate lower than 5Hz
// is recommended to avoid a known issue with satellites disappearing.
const uint8_t GPS::_message_1HZ[] = {
0xE8, 0x03, // Measurement Rate (1000ms for 1Hz)
0x01, 0x00, // Navigation rate, always 1 in GPS mode
0x01, 0x00, // Time reference
};
// Disable GGL. GGL - Geographic position (latitude and longitude), which provides the current geographical
// coordinates.
const uint8_t GPS::_message_GGL[] = {
0xF0, 0x01, // NMEA ID for GLL
0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI
0x00, // Disable
0x01, 0x01, 0x01, 0x01 // Reserved
};
// Enable GSA. GSA - GPS DOP and active satellites, used for detailing the satellites used in the positioning and
// the DOP (Dilution of Precision)
const uint8_t GPS::_message_GSA[] = {
0xF0, 0x02, // NMEA ID for GSA
0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI
0x01, // Enable
0x01, 0x01, 0x01, 0x01 // Reserved
};
// Disable GSV. GSV - Satellites in view, details the number and location of satellites in view.
const uint8_t GPS::_message_GSV[] = {
0xF0, 0x03, // NMEA ID for GSV
0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI
0x00, // Disable
0x01, 0x01, 0x01, 0x01 // Reserved
};
// Disable VTG. VTG - Track made good and ground speed, which provides course and speed information relative to
// the ground.
const uint8_t GPS::_message_VTG[] = {
0xF0, 0x05, // NMEA ID for VTG
0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI
0x00, // Disable
0x01, 0x01, 0x01, 0x01 // Reserved
};
// Enable RMC. RMC - Recommended Minimum data, the essential gps pvt (position, velocity, time) data.
const uint8_t GPS::_message_RMC[] = {
0xF0, 0x04, // NMEA ID for RMC
0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI
0x01, // Enable
0x01, 0x01, 0x01, 0x01 // Reserved
};
// Enable GGA. GGA - Global Positioning System Fix Data, which provides 3D location and accuracy data.
const uint8_t GPS::_message_GGA[] = {
0xF0, 0x00, // NMEA ID for GGA
0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI
0x01, // Enable
0x01, 0x01, 0x01, 0x01 // Reserved
};
// The Power Management configuration allows the GPS module to operate in different power modes for optimized
// power consumption. The modes supported are: 0x00 = Full power: The module operates at full power with no power
// saving. 0x01 = Balanced: The module dynamically adjusts the tracking behavior to balance power consumption.
// 0x02 = Interval: The module operates in a periodic mode, cycling between tracking and power saving states.
// 0x03 = Aggressive with 1 Hz: The module operates in a power saving mode with a 1 Hz update rate.
// 0x04 = Aggressive with 2 Hz: The module operates in a power saving mode with a 2 Hz update rate.
// 0x05 = Aggressive with 4 Hz: The module operates in a power saving mode with a 4 Hz update rate.
// The 'period' field specifies the position update and search period. It is only valid when the powerSetupValue
// is set to Interval; otherwise, it must be set to '0'. The 'onTime' field specifies the duration of the ON phase
// and must be smaller than the period. It is only valid when the powerSetupValue is set to Interval; otherwise,
// it must be set to '0'.
const uint8_t GPS::_message_PMS[] = {
0x00, // Version (0)
0x03, // Power setup value
0x00, 0x00, // period: not applicable, set to 0
0x00, 0x00, // onTime: not applicable, set to 0
0x97, 0x6F // reserved, generated by u-center
};
const uint8_t GPS::_message_SAVE[] = {
0x00, 0x00, 0x00, 0x00, // clearMask: no sections cleared
0xFF, 0xFF, 0x00, 0x00, // saveMask: save all sections
0x00, 0x00, 0x00, 0x00, // loadMask: no sections loaded
0x0F // deviceMask: BBR, Flash, EEPROM, and SPI Flash
};

View File

@@ -1,5 +1,3 @@
#include "main.h"
#ifdef HAS_NCP5623
#include <NCP5623.h>
extern NCP5623 rgb;

View File

@@ -164,11 +164,28 @@ static void drawIconScreen(const char *upperMsg, OLEDDisplay *display, OLEDDispl
// FIXME - draw serial # somewhere?
}
#ifdef ARCH_ESP32
static void drawFrameResume(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
uint16_t x_offset = display->width() / 2;
display->setTextAlignment(TEXT_ALIGN_CENTER);
display->setFont(FONT_MEDIUM);
display->drawString(x_offset + x, 26 + y, "Resuming...");
}
#endif
static void drawBootScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
// Draw region in upper left
const char *region = myRegion ? myRegion->name : NULL;
drawIconScreen(region, display, state, x, y);
#ifdef ARCH_ESP32
if (wakeCause == ESP_SLEEP_WAKEUP_TIMER || wakeCause == ESP_SLEEP_WAKEUP_EXT1) {
drawFrameResume(display, state, x, y);
} else
#endif
{
// Draw region in upper left
const char *region = myRegion ? myRegion->name : NULL;
drawIconScreen(region, display, state, x, y);
}
}
static void drawOEMIconScreen(const char *upperMsg, OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)

View File

@@ -5,12 +5,12 @@ RotaryEncoderInterruptImpl1 *rotaryEncoderInterruptImpl1;
RotaryEncoderInterruptImpl1::RotaryEncoderInterruptImpl1() : RotaryEncoderInterruptBase("rotEnc1") {}
void RotaryEncoderInterruptImpl1::init()
bool RotaryEncoderInterruptImpl1::init()
{
if (!moduleConfig.canned_message.rotary1_enabled) {
// Input device is disabled.
disable();
return;
return false;
}
uint8_t pinA = moduleConfig.canned_message.inputbroker_pin_a;
@@ -25,6 +25,7 @@ void RotaryEncoderInterruptImpl1::init()
RotaryEncoderInterruptImpl1::handleIntA, RotaryEncoderInterruptImpl1::handleIntB,
RotaryEncoderInterruptImpl1::handleIntPressed);
inputBroker->registerSource(this);
return true;
}
void RotaryEncoderInterruptImpl1::handleIntA()
@@ -38,4 +39,4 @@ void RotaryEncoderInterruptImpl1::handleIntB()
void RotaryEncoderInterruptImpl1::handleIntPressed()
{
rotaryEncoderInterruptImpl1->intPressHandler();
}
}

View File

@@ -12,7 +12,7 @@ class RotaryEncoderInterruptImpl1 : public RotaryEncoderInterruptBase
{
public:
RotaryEncoderInterruptImpl1();
void init();
bool init();
static void handleIntA();
static void handleIntB();
static void handleIntPressed();

View File

@@ -5,12 +5,12 @@ UpDownInterruptImpl1 *upDownInterruptImpl1;
UpDownInterruptImpl1::UpDownInterruptImpl1() : UpDownInterruptBase("upDown1") {}
void UpDownInterruptImpl1::init()
bool UpDownInterruptImpl1::init()
{
if (!moduleConfig.canned_message.updown1_enabled) {
// Input device is disabled.
return;
return false;
}
uint8_t pinUp = moduleConfig.canned_message.inputbroker_pin_a;
@@ -24,6 +24,7 @@ void UpDownInterruptImpl1::init()
UpDownInterruptBase::init(pinDown, pinUp, pinPress, eventDown, eventUp, eventPressed, UpDownInterruptImpl1::handleIntDown,
UpDownInterruptImpl1::handleIntUp, UpDownInterruptImpl1::handleIntPressed);
inputBroker->registerSource(this);
return true;
}
void UpDownInterruptImpl1::handleIntDown()
@@ -37,4 +38,4 @@ void UpDownInterruptImpl1::handleIntUp()
void UpDownInterruptImpl1::handleIntPressed()
{
upDownInterruptImpl1->intPressHandler();
}
}

View File

@@ -5,10 +5,10 @@ class UpDownInterruptImpl1 : public UpDownInterruptBase
{
public:
UpDownInterruptImpl1();
void init();
bool init();
static void handleIntDown();
static void handleIntUp();
static void handleIntPressed();
};
extern UpDownInterruptImpl1 *upDownInterruptImpl1;
extern UpDownInterruptImpl1 *upDownInterruptImpl1;

View File

@@ -73,6 +73,7 @@ NRF52Bluetooth *nrf52Bluetooth;
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
#include "AccelerometerThread.h"
#include "AmbientLightingThread.h"
#endif
using namespace concurrency;
@@ -169,6 +170,7 @@ static OSThread *buttonThread;
uint32_t ButtonThread::longPressTime = 0;
#endif
static OSThread *accelerometerThread;
static OSThread *ambientLightingThread;
SPISettings spiSettings(4000000, MSBFIRST, SPI_MODE0);
RadioInterface *rIf = NULL;
@@ -219,11 +221,6 @@ void setup()
digitalWrite(VEXT_ENABLE, 0); // turn on the display power
#endif
#ifdef VGNSS_CTRL
pinMode(VGNSS_CTRL, OUTPUT);
digitalWrite(VGNSS_CTRL, LOW);
#endif
#if defined(VTFT_CTRL)
pinMode(VTFT_CTRL, OUTPUT);
digitalWrite(VTFT_CTRL, LOW);
@@ -409,14 +406,6 @@ void setup()
// Only one supported RGB LED currently
#ifdef HAS_NCP5623
rgb_found = i2cScanner->find(ScanI2C::DeviceType::NCP5623);
// Start the RGB LED at 50%
if (rgb_found.type == ScanI2C::NCP5623) {
rgb.begin();
rgb.setCurrent(10);
rgb.setColor(128, 128, 128);
}
#endif
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
@@ -521,6 +510,12 @@ void setup()
}
#endif
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
if (rgb_found.type != ScanI2C::DeviceType::NONE) {
ambientLightingThread = new AmbientLightingThread(rgb_found.type);
}
#endif
#ifdef T_WATCH_S3
drv.begin();
drv.selectLibrary(1);
@@ -558,14 +553,12 @@ void setup()
readFromRTC(); // read the main CPU RTC at first (in case we can't get GPS time)
gps = createGps();
gps = GPS::createGps();
if (gps) {
gpsStatus->observe(&gps->newStatus);
} else {
LOG_WARN("No GPS found - running without GPS\n");
LOG_DEBUG("Running without GPS.\n");
}
nodeStatus->observe(&nodeDB.newStatus);
service.init();
@@ -590,17 +583,6 @@ void setup()
screen->print("Started...\n");
// We have now loaded our saved preferences from flash
// ONCE we will factory reset the GPS for bug #327
if (gps && !devicestate.did_gps_reset) {
LOG_WARN("GPS FactoryReset requested\n");
if (gps->factoryReset()) { // If we don't succeed try again next time
devicestate.did_gps_reset = true;
nodeDB.saveToDisk(SEGMENT_DEVICESTATE);
}
}
#ifdef SX126X_ANT_SW
// make analog PA vs not PA switch on SX126x eval board work properly
pinMode(SX126X_ANT_SW, OUTPUT);
@@ -755,7 +737,6 @@ void setup()
PowerFSM_setup(); // we will transition to ON in a couple of seconds, FIXME, only do this for cold boots, not waking from SDS
powerFSMthread = new PowerFSMThread();
// setBluetoothEnable(false); we now don't start bluetooth until we enter the proper state
setCPUFast(false); // 80MHz is fine for our slow peripherals
}

View File

@@ -338,10 +338,8 @@ int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus)
pos = ConvertToPosition(node->position);
}
// Finally add a fresh timestamp and battery level reading
// I KNOW this is redundant with refreshLocalMeshNode() above, but these are
// inexpensive nonblocking calls and can be refactored in due course
pos.time = getValidTime(RTCQualityGPS);
// Add a fresh timestamp
pos.time = getValidTime(RTCQualityFromNet);
// In debug logs, identify position by @timestamp:stage (stage 4 = nodeDB)
LOG_DEBUG("onGPSChanged() pos@%x, time=%u, lat=%d, lon=%d, alt=%d\n", pos.timestamp, pos.time, pos.latitude_i,

View File

@@ -169,6 +169,14 @@ void NodeDB::installDefaultConfig()
config.lora.region = meshtastic_Config_LoRaConfig_RegionCode_UNSET;
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST;
config.lora.hop_limit = HOP_RELIABLE;
#ifdef PIN_GPS_EN
config.position.gps_en_gpio = PIN_GPS_EN;
#endif
#ifdef GPS_POWER_TOGGLE
config.device.disable_triple_click = false;
#else
config.device.disable_triple_click = true;
#endif
config.position.gps_enabled = true;
config.position.position_broadcast_smart_enabled = true;
config.position.broadcast_smart_minimum_distance = 100;
@@ -255,6 +263,13 @@ void NodeDB::installDefaultModuleConfig()
moduleConfig.detection_sensor.detection_triggered_high = true;
moduleConfig.detection_sensor.minimum_broadcast_secs = 45;
moduleConfig.has_ambient_lighting = true;
moduleConfig.ambient_lighting.current = 10;
// Default to a color based on our node number
moduleConfig.ambient_lighting.red = (myNodeInfo.my_node_num & 0xFF0000) >> 16;
moduleConfig.ambient_lighting.green = (myNodeInfo.my_node_num & 0x00FF00) >> 8;
moduleConfig.ambient_lighting.blue = myNodeInfo.my_node_num & 0x0000FF;
initModuleConfigIntervals();
}
@@ -297,6 +312,19 @@ void NodeDB::resetNodes()
neighborInfoModule->resetNeighbors();
}
void NodeDB::cleanupMeshDB()
{
int newPos = 0, removed = 0;
for (int i = 0; i < *numMeshNodes; i++) {
if (meshNodes[i].has_user)
meshNodes[newPos++] = meshNodes[i];
else
removed++;
}
*numMeshNodes -= removed;
LOG_DEBUG("cleanupMeshDB purged %d entries\n", removed);
}
void NodeDB::installDefaultDeviceState()
{
LOG_INFO("Installing default DeviceState\n");
@@ -326,6 +354,7 @@ void NodeDB::init()
{
LOG_INFO("Initializing NodeDB\n");
loadFromDisk();
cleanupMeshDB();
uint32_t devicestateCRC = crc32Buffer(&devicestate, sizeof(devicestate));
uint32_t configCRC = crc32Buffer(&config, sizeof(config));
@@ -381,25 +410,20 @@ void NodeDB::init()
*/
void NodeDB::pickNewNodeNum()
{
NodeNum r = myNodeInfo.my_node_num;
getMacAddr(ourMacAddr); // Make sure ourMacAddr is set
// Pick an initial nodenum based on the macaddr
r = (ourMacAddr[2] << 24) | (ourMacAddr[3] << 16) | (ourMacAddr[4] << 8) | ourMacAddr[5];
if (r == NODENUM_BROADCAST || r < NUM_RESERVED)
r = NUM_RESERVED; // don't pick a reserved node number
NodeNum nodeNum = (ourMacAddr[2] << 24) | (ourMacAddr[3] << 16) | (ourMacAddr[4] << 8) | ourMacAddr[5];
meshtastic_NodeInfoLite *found;
while ((found = getMeshNode(r)) && memcmp(found->user.macaddr, owner.macaddr, sizeof(owner.macaddr))) {
// FIXME: input for random() is int, so NODENUM_BROADCAST becomes -1
NodeNum n = random(NUM_RESERVED, NODENUM_BROADCAST); // try a new random choice
LOG_WARN("NOTE! Our desired nodenum 0x%x is in use, so trying for 0x%x\n", r, n);
r = n;
while ((nodeNum == NODENUM_BROADCAST || nodeNum < NUM_RESERVED) ||
((found = getMeshNode(nodeNum)) && memcmp(found->user.macaddr, owner.macaddr, sizeof(owner.macaddr)) != 0)) {
NodeNum candidate = random(NUM_RESERVED, LONG_MAX); // try a new random choice
LOG_WARN("NOTE! Our desired nodenum 0x%x is invalid or in use, so trying for 0x%x\n", nodeNum, candidate);
nodeNum = candidate;
}
myNodeInfo.my_node_num = r;
myNodeInfo.my_node_num = nodeNum;
}
static const char *prefFileName = "/prefs/db.proto";

View File

@@ -146,6 +146,9 @@ class NodeDB
/// read our db from flash
void loadFromDisk();
/// purge db entries without user info
void cleanupMeshDB();
/// Reinit device state from scratch (not loading from disk)
void installDefaultDeviceState(), installDefaultChannels(), installDefaultConfig(), installDefaultModuleConfig();
};
@@ -189,7 +192,7 @@ extern NodeDB nodeDB;
#define default_sds_secs IF_ROUTER(ONE_DAY, UINT32_MAX) // Default to forever super deep sleep
#define default_ls_secs IF_ROUTER(ONE_DAY, 5 * 60)
#define default_min_wake_secs 10
#define default_screen_on_secs 60 * 10
#define default_screen_on_secs IF_ROUTER(1, 60 * 10)
#define default_mqtt_address "mqtt.meshtastic.org"
#define default_mqtt_username "meshdev"
@@ -209,6 +212,14 @@ inline uint32_t getConfiguredOrDefaultMs(uint32_t configuredInterval, uint32_t d
return defaultInterval * 1000;
}
inline uint32_t getConfiguredOrDefault(uint32_t configured, uint32_t defaultValue)
{
if (configured > 0)
return configured;
return defaultValue;
}
/// Sometimes we will have Position objects that only have a time, so check for
/// valid lat/lon
static inline bool hasValidPosition(const meshtastic_NodeInfoLite *n)

View File

@@ -155,11 +155,18 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
// app not to send locations on our behalf.
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_my_info_tag;
fromRadioScratch.my_info = myNodeInfo;
state = STATE_SEND_NODEINFO;
state = STATE_SEND_METADATA;
service.refreshLocalMeshNode(); // Update my NodeInfo because the client will be asking for it soon.
break;
case STATE_SEND_METADATA:
LOG_INFO("getFromRadio=STATE_SEND_METADATA\n");
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_metadata_tag;
fromRadioScratch.metadata = getDeviceMetadata();
state = STATE_SEND_NODEINFO;
break;
case STATE_SEND_NODEINFO: {
LOG_INFO("getFromRadio=STATE_SEND_NODEINFO\n");
@@ -294,15 +301,11 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
config_state++;
// Advance when we have sent all of our ModuleConfig objects
if (config_state > (_meshtastic_AdminMessage_ModuleConfigType_MAX + 1)) {
state = STATE_SEND_METADATA;
state = STATE_SEND_COMPLETE_ID;
config_state = 0;
}
break;
case STATE_SEND_METADATA:
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_metadata_tag;
fromRadioScratch.metadata = getDeviceMetadata();
state = STATE_SEND_COMPLETE_ID;
break;
case STATE_SEND_COMPLETE_ID:
LOG_INFO("getFromRadio=STATE_SEND_COMPLETE_ID\n");
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_config_complete_id_tag;

View File

@@ -534,8 +534,8 @@ size_t RadioInterface::beginSending(meshtastic_MeshPacket *p)
h->id = p->id;
h->channel = p->channel;
if (p->hop_limit > HOP_MAX) {
LOG_WARN("hop limit %d is too high, setting to %d\n", p->hop_limit, HOP_MAX);
p->hop_limit = HOP_MAX;
LOG_WARN("hop limit %d is too high, setting to %d\n", p->hop_limit, HOP_RELIABLE);
p->hop_limit = HOP_RELIABLE;
}
h->flags = p->hop_limit | (p->want_ack ? PACKET_FLAGS_WANT_ACK_MASK : 0);

View File

@@ -3,7 +3,8 @@
#include "error.h"
#include "mesh/NodeDB.h"
// Particular boards might define a different max power based on what their hardware can do
// Particular boards might define a different max power based on what their hardware can do, default to max power output if not
// specified (may be dangerous if using external PA and SX126x power config forgotten)
#ifndef SX126X_MAX_POWER
#define SX126X_MAX_POWER 22
#endif
@@ -26,20 +27,23 @@ template <typename T> bool SX126xInterface<T>::init()
pinMode(SX126X_POWER_EN, OUTPUT);
#endif
#ifndef SX126X_E22
float tcxoVoltage = 0; // None - we use an XTAL
// FIXME: correct logic to default to not using TCXO if no voltage is specified for SX126X_DIO3_TCXO_VOLTAGE
#if !defined(SX126X_DIO3_TCXO_VOLTAGE)
float tcxoVoltage =
0; // "TCXO reference voltage to be set on DIO3. Defaults to 1.6 V, set to 0 to skip." per
// https://github.com/jgromes/RadioLib/blob/690a050ebb46e6097c5d00c371e961c1caa3b52e/src/modules/SX126x/SX126x.h#L471C26-L471C104
// (DIO3 is free to be used as an IRQ)
LOG_DEBUG("SX126X_DIO3_TCXO_VOLTAGE not defined, not using DIO3 as TCXO reference voltage\n");
#else
// Use DIO3 to power tcxo per https://github.com/jgromes/RadioLib/issues/12#issuecomment-520695575
float tcxoVoltage = 1.8;
float tcxoVoltage = SX126X_DIO3_TCXO_VOLTAGE;
LOG_DEBUG("SX126X_DIO3_TCXO_VOLTAGE defined, using DIO3 as TCXO reference voltage at %f V\n", SX126X_DIO3_TCXO_VOLTAGE);
// (DIO3 is not free to be used as an IRQ)
#endif
// FIXME: May want to set depending on a definition, currently all SX126x variant files use the DC-DC regulator option
bool useRegulatorLDO = false; // Seems to depend on the connection to pin 9/DCC_SW - if an inductor DCDC?
RadioLibInterface::init();
if (power == 0)
power = SX126X_MAX_POWER;
if (power > SX126X_MAX_POWER) // This chip has lower power limits than some
if (power > SX126X_MAX_POWER) // Clamp power to maximum defined level
power = SX126X_MAX_POWER;
limitPower();
@@ -54,49 +58,50 @@ template <typename T> bool SX126xInterface<T>::init()
LOG_INFO("Bandwidth set to %f\n", bw);
LOG_INFO("Power output set to %d\n", power);
// current limit was removed from module' ctor
// override default value (60 mA)
// Overriding current limit
// (https://github.com/jgromes/RadioLib/blob/690a050ebb46e6097c5d00c371e961c1caa3b52e/src/modules/SX126x/SX126x.cpp#L85) using
// value in SX126xInterface.h (currently 140 mA) It may or may not be neccessary, depending on how RadioLib functions, from
// SX1261/2 datasheet: OCP after setting DeviceSel with SetPaConfig(): SX1261 - 60 mA, SX1262 - 140 mA For the SX1268 the IC
// defaults to 140mA no matter the set power level, but RadioLib set it lower, this would need further checking Default values
// are: SX1262, SX1268: 0x38 (140 mA), SX1261: 0x18 (60 mA)
// FIXME: Not ideal to increase SX1261 current limit above 60mA as it can only transmit max 15dBm, should probably only do it
// if using SX1262 or SX1268
res = lora.setCurrentLimit(currentLimit);
LOG_DEBUG("Current limit set to %f\n", currentLimit);
LOG_DEBUG("Current limit set result %d\n", res);
#if defined(SX126X_E22)
// E22 Emulation explicitly requires DIO2 as RF switch, so set it to TRUE again for good measure. In case somebody defines
// SX126X_TX for an E22 Module
if (res == RADIOLIB_ERR_NONE) {
LOG_DEBUG("SX126X_E22 mode enabled. Setting DIO2 as RF Switch\n");
res = lora.setDio2AsRfSwitch(true);
}
#ifdef SX126X_DIO2_AS_RF_SWITCH
LOG_DEBUG("Setting DIO2 as RF switch\n");
bool dio2AsRfSwitch = true;
#else
LOG_DEBUG("Setting DIO2 as not RF switch\n");
bool dio2AsRfSwitch = false;
#endif
if (res == RADIOLIB_ERR_NONE) {
res = lora.setDio2AsRfSwitch(dio2AsRfSwitch);
}
#if defined(SX126X_TXEN) && (SX126X_TXEN != RADIOLIB_NC)
// If SX126X_TXEN is connected to the MCU, we are manually controlling RX and TX.
// But lora.begin (called above) sets Dio2 as RF switch control, which is not true here, so set it back to false.
if (res == RADIOLIB_ERR_NONE) {
LOG_DEBUG("SX126X_TXEN pin defined. Setting RF Switch: RXEN=%i, TXEN=%i\n", SX126X_RXEN, SX126X_TXEN);
res = lora.setDio2AsRfSwitch(false);
lora.setRfSwitchPins(SX126X_RXEN, SX126X_TXEN);
}
#elif defined(SX126X_RXEN) && (SX126X_RXEN != RADIOLIB_NC && defined(E22_TXEN_CONNECTED_TO_DIO2))
// Otherwise, if SX126X_RXEN is connected to the MCU, and E22_TXEN_CONNECTED_TO_DIO2 is defined, we are letting the
// E22 control RX and TX via DIO2. In this configuration, the E22's TXEN and DIO2 pins are connected to each other,
// but not to the MCU.
// However, we must still connect the E22's RXEN pin to the MCU, define SX126X_RXEN accordingly, and then call
// setRfSwitchPins, otherwise RX sensitivity (observed via RSSI) is greatly diminished.
LOG_DEBUG("SX126X_RXEN and E22_TXEN_CONNECTED_TO_DIO2 are defined; value of res: %d", res);
if (res == RADIOLIB_ERR_NONE) {
LOG_DEBUG("SX126X_TXEN is RADIOLIB_NC, but SX126X_RXEN and E22_TXEN_CONNECTED_TO_DIO2 are both defined; calling "
"lora.setRfSwitchPins.");
lora.setRfSwitchPins(SX126X_RXEN, SX126X_TXEN);
}
// If a pin isn't defined, we set it to RADIOLIB_NC, it is safe to always do external RF switching with RADIOLIB_NC as it has
// no effect
#ifndef SX126X_RXEN
#define SX126X_RXEN RADIOLIB_NC
LOG_DEBUG("SX126X_RXEN not defined, defaulting to RADIOLIB_NC\n");
#endif
#ifndef SX126X_TXEN
#define SX126X_TXEN RADIOLIB_NC
LOG_DEBUG("SX126X_TXEN not defined, defaulting to RADIOLIB_NC\n");
#endif
if (res == RADIOLIB_ERR_NONE) {
LOG_DEBUG("Using MCU pin %i as RXEN and pin %i as TXEN to control RF switching\n", SX126X_RXEN, SX126X_TXEN);
lora.setRfSwitchPins(SX126X_RXEN, SX126X_TXEN);
}
if (config.lora.sx126x_rx_boosted_gain) {
uint16_t result = lora.setRxBoostedGainMode(true);
LOG_INFO("Set Rx Boosted Gain mode; result: %d\n", result);
LOG_INFO("Set RX gain to boosted mode; result: %d\n", result);
} else {
uint16_t result = lora.setRxBoostedGainMode(false);
LOG_INFO("Set Rx Power Saving Gain mode; result: %d\n", result);
LOG_INFO("Set RX gain to power saving mode (boosted mode off); result: %d\n", result);
}
#if 0
@@ -265,7 +270,7 @@ template <typename T> bool SX126xInterface<T>::isChannelActive()
/** Could we send right now (i.e. either not actively receiving or transmitting)? */
template <typename T> bool SX126xInterface<T>::isActivelyReceiving()
{
// The IRQ status will be cleared when we start our read operation. Check if we've started a header, but haven't yet
// The IRQ status will be cleared when we start our read operation. Check if we've started a header, but haven't yet
// received and handled the interrupt for reading the packet/handling errors.
uint16_t irq = lora.getIrqStatus();
@@ -296,7 +301,7 @@ template <typename T> bool SX126xInterface<T>::sleep()
{
// Not keeping config is busted - next time nrf52 board boots lora sending fails tcxo related? - see datasheet
// \todo Display actual typename of the adapter, not just `SX126x`
LOG_DEBUG("sx126x entering sleep mode (FIXME, don't keep config)\n");
LOG_DEBUG("SX126x entering sleep mode (FIXME, don't keep config)\n");
setStandby(); // Stop any pending operations
// turn off TCXO if it was powered
@@ -312,4 +317,4 @@ template <typename T> bool SX126xInterface<T>::sleep()
#endif
return true;
}
}

View File

@@ -30,10 +30,14 @@ typedef enum _meshtastic_Config_DeviceConfig_Role {
or any other packet type. They will simply rebroadcast any mesh packets on the same frequency, channel num, spread factor, and coding rate. */
meshtastic_Config_DeviceConfig_Role_REPEATER = 4,
/* Tracker device role
Position Mesh packets will be prioritized higher and sent more frequently by default. */
Position Mesh packets will be prioritized higher and sent more frequently by default.
When used in conjunction with power.is_power_saving = true, nodes will wake up,
send position, and then sleep for position.position_broadcast_secs seconds. */
meshtastic_Config_DeviceConfig_Role_TRACKER = 5,
/* Sensor device role
Telemetry Mesh packets will be prioritized higher and sent more frequently by default. */
Telemetry Mesh packets will be prioritized higher and sent more frequently by default.
When used in conjunction with power.is_power_saving = true, nodes will wake up,
send environment telemetry, and then sleep for telemetry.environment_update_interval seconds. */
meshtastic_Config_DeviceConfig_Role_SENSOR = 6
} meshtastic_Config_DeviceConfig_Role;
@@ -237,6 +241,8 @@ typedef struct _meshtastic_Config_DeviceConfig {
/* If true, device is considered to be "managed" by a mesh administrator
Clients should then limit available configuration and administrative options inside the user interface */
bool is_managed;
/* Disables the triple-press of user button to enable or disable GPS */
bool disable_triple_click;
} meshtastic_Config_DeviceConfig;
/* Position Config */
@@ -272,6 +278,8 @@ typedef struct _meshtastic_Config_PositionConfig {
uint32_t broadcast_smart_minimum_distance;
/* The minimum number of seconds (since the last send) before we can send a position to the mesh if position_broadcast_smart_enabled */
uint32_t broadcast_smart_minimum_interval_secs;
/* (Re)define PIN_GPS_EN for your board. */
uint32_t gps_en_gpio;
} meshtastic_Config_PositionConfig;
/* Power Config\
@@ -399,7 +407,8 @@ typedef struct _meshtastic_Config_LoRaConfig {
/* The region code for the radio (US, CN, EU433, etc...) */
meshtastic_Config_LoRaConfig_RegionCode region;
/* Maximum number of hops. This can't be greater than 7.
Default of 3 */
Default of 3
Attempting to set a value > 7 results in the default */
uint32_t hop_limit;
/* Disable TX from the LoRa radio. Useful for hot-swapping antennas and other tests.
Defaults to false */
@@ -530,8 +539,8 @@ extern "C" {
/* Initializer values for message structs */
#define meshtastic_Config_init_default {0, {meshtastic_Config_DeviceConfig_init_default}}
#define meshtastic_Config_DeviceConfig_init_default {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0}
#define meshtastic_Config_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_Config_DeviceConfig_init_default {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0}
#define meshtastic_Config_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_Config_PowerConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_Config_NetworkConfig_init_default {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_default, ""}
#define meshtastic_Config_NetworkConfig_IpV4Config_init_default {0, 0, 0, 0}
@@ -539,8 +548,8 @@ extern "C" {
#define meshtastic_Config_LoRaConfig_init_default {0, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _meshtastic_Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}}
#define meshtastic_Config_BluetoothConfig_init_default {0, _meshtastic_Config_BluetoothConfig_PairingMode_MIN, 0}
#define meshtastic_Config_init_zero {0, {meshtastic_Config_DeviceConfig_init_zero}}
#define meshtastic_Config_DeviceConfig_init_zero {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0}
#define meshtastic_Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_Config_DeviceConfig_init_zero {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0}
#define meshtastic_Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_Config_PowerConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_Config_NetworkConfig_init_zero {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_zero, ""}
#define meshtastic_Config_NetworkConfig_IpV4Config_init_zero {0, 0, 0, 0}
@@ -558,6 +567,7 @@ extern "C" {
#define meshtastic_Config_DeviceConfig_node_info_broadcast_secs_tag 7
#define meshtastic_Config_DeviceConfig_double_tap_as_button_press_tag 8
#define meshtastic_Config_DeviceConfig_is_managed_tag 9
#define meshtastic_Config_DeviceConfig_disable_triple_click_tag 10
#define meshtastic_Config_PositionConfig_position_broadcast_secs_tag 1
#define meshtastic_Config_PositionConfig_position_broadcast_smart_enabled_tag 2
#define meshtastic_Config_PositionConfig_fixed_position_tag 3
@@ -569,6 +579,7 @@ extern "C" {
#define meshtastic_Config_PositionConfig_tx_gpio_tag 9
#define meshtastic_Config_PositionConfig_broadcast_smart_minimum_distance_tag 10
#define meshtastic_Config_PositionConfig_broadcast_smart_minimum_interval_secs_tag 11
#define meshtastic_Config_PositionConfig_gps_en_gpio_tag 12
#define meshtastic_Config_PowerConfig_is_power_saving_tag 1
#define meshtastic_Config_PowerConfig_on_battery_shutdown_after_secs_tag 2
#define meshtastic_Config_PowerConfig_adc_multiplier_override_tag 3
@@ -653,7 +664,8 @@ X(a, STATIC, SINGULAR, UINT32, buzzer_gpio, 5) \
X(a, STATIC, SINGULAR, UENUM, rebroadcast_mode, 6) \
X(a, STATIC, SINGULAR, UINT32, node_info_broadcast_secs, 7) \
X(a, STATIC, SINGULAR, BOOL, double_tap_as_button_press, 8) \
X(a, STATIC, SINGULAR, BOOL, is_managed, 9)
X(a, STATIC, SINGULAR, BOOL, is_managed, 9) \
X(a, STATIC, SINGULAR, BOOL, disable_triple_click, 10)
#define meshtastic_Config_DeviceConfig_CALLBACK NULL
#define meshtastic_Config_DeviceConfig_DEFAULT NULL
@@ -668,7 +680,8 @@ X(a, STATIC, SINGULAR, UINT32, position_flags, 7) \
X(a, STATIC, SINGULAR, UINT32, rx_gpio, 8) \
X(a, STATIC, SINGULAR, UINT32, tx_gpio, 9) \
X(a, STATIC, SINGULAR, UINT32, broadcast_smart_minimum_distance, 10) \
X(a, STATIC, SINGULAR, UINT32, broadcast_smart_minimum_interval_secs, 11)
X(a, STATIC, SINGULAR, UINT32, broadcast_smart_minimum_interval_secs, 11) \
X(a, STATIC, SINGULAR, UINT32, gps_en_gpio, 12)
#define meshtastic_Config_PositionConfig_CALLBACK NULL
#define meshtastic_Config_PositionConfig_DEFAULT NULL
@@ -768,12 +781,12 @@ extern const pb_msgdesc_t meshtastic_Config_BluetoothConfig_msg;
/* Maximum encoded size of messages (where known) */
#define meshtastic_Config_BluetoothConfig_size 10
#define meshtastic_Config_DeviceConfig_size 30
#define meshtastic_Config_DeviceConfig_size 32
#define meshtastic_Config_DisplayConfig_size 28
#define meshtastic_Config_LoRaConfig_size 77
#define meshtastic_Config_NetworkConfig_IpV4Config_size 20
#define meshtastic_Config_NetworkConfig_size 195
#define meshtastic_Config_PositionConfig_size 54
#define meshtastic_Config_PositionConfig_size 60
#define meshtastic_Config_PowerConfig_size 40
#define meshtastic_Config_size 198

View File

@@ -316,7 +316,7 @@ extern const pb_msgdesc_t meshtastic_NodeRemoteHardwarePin_msg;
#define meshtastic_DeviceState_size 16854
#define meshtastic_NodeInfoLite_size 151
#define meshtastic_NodeRemoteHardwarePin_size 29
#define meshtastic_OEMStore_size 3210
#define meshtastic_OEMStore_size 3218
#define meshtastic_PositionLite_size 28
#ifdef __cplusplus

View File

@@ -174,7 +174,7 @@ extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg;
#define meshtastic_LocalModuleConfig_fields &meshtastic_LocalModuleConfig_msg
/* Maximum encoded size of messages (where known) */
#define meshtastic_LocalConfig_size 455
#define meshtastic_LocalConfig_size 463
#define meshtastic_LocalModuleConfig_size 609
#ifdef __cplusplus

View File

@@ -299,9 +299,8 @@ typedef struct _meshtastic_Position {
/* In meters above MSL (but see issue #359) */
int32_t altitude;
/* This is usually not sent over the mesh (to save space), but it is sent
from the phone so that the local device can set its RTC If it is sent over
the mesh (because there are devices on the mesh without GPS), it will only
be sent by devices which has a hardware GPS clock.
from the phone so that the local device can set its time if it is sent over
the mesh (because there are devices on the mesh without GPS or RTC).
seconds since 1970 */
uint32_t time;
/* TODO: REPLACE */

View File

@@ -313,13 +313,14 @@ Initially created for the RAK14001 RGB LED module. */
typedef struct _meshtastic_ModuleConfig_AmbientLightingConfig {
/* Sets LED to on or off. */
bool led_state;
/* Sets the overall current for the LED, firmware side range for the RAK14001 is 1-31, but users should be given a range of 0-100% */
/* Sets the current for the LED output. Default is 10. */
uint8_t current;
uint8_t red; /* Red level */
/* Sets the green level of the LED, firmware side values are 0-255, but users should be given a range of 0-100% */
uint8_t green; /* Green level */
/* Sets the blue level of the LED, firmware side values are 0-255, but users should be given a range of 0-100% */
uint8_t blue; /* Blue level */
/* Sets the red LED level. Values are 0-255. */
uint8_t red;
/* Sets the green LED level. Values are 0-255. */
uint8_t green;
/* Sets the blue LED level. Values are 0-255. */
uint8_t blue;
} meshtastic_ModuleConfig_AmbientLightingConfig;
/* A GPIO pin definition for remote hardware module */

View File

@@ -69,7 +69,8 @@ typedef enum _meshtastic_PortNum {
NOTE: audio frames contain a 3 byte header (0xc0 0xde 0xc2) and a one byte marker for the decompressed bitrate.
This marker comes from the 'moduleConfig.audio.bitrate' enum minus one. */
meshtastic_PortNum_AUDIO_APP = 9,
/* Same as Text Message but originating from Detection Sensor Module. */
/* Same as Text Message but originating from Detection Sensor Module.
NOTE: This portnum traffic is not sent to the public MQTT starting at firmware version 2.2.9 */
meshtastic_PortNum_DETECTION_SENSOR_APP = 10,
/* Provides a 'ping' service that replies to any packet it receives.
Also serves as a small example module.
@@ -90,7 +91,8 @@ typedef enum _meshtastic_PortNum {
ENCODING: Protobuf */
meshtastic_PortNum_STORE_FORWARD_APP = 65,
/* Optional port for messages for the range test module.
ENCODING: ASCII Plaintext */
ENCODING: ASCII Plaintext
NOTE: This portnum traffic is not sent to the public MQTT starting at firmware version 2.2.9 */
meshtastic_PortNum_RANGE_TEST_APP = 66,
/* Provides a format to send and receive telemetry data from the Meshtastic network.
Maintained by Charles Crossan (crossan007) : crossan007@gmail.com

View File

@@ -101,11 +101,7 @@ typedef struct _meshtastic_AirQualityMetrics {
/* Types of Measurements the telemetry module is equipped to handle */
typedef struct _meshtastic_Telemetry {
/* This is usually not sent over the mesh (to save space), but it is sent
from the phone so that the local device can set its RTC If it is sent over
the mesh (because there are devices on the mesh without GPS), it will only
be sent by devices which has a hardware GPS clock (IE Mobile Phone).
seconds since 1970 */
/* Seconds since 1970 - or 0 for unknown/unset */
uint32_t time;
pb_size_t which_variant;
union {

View File

@@ -25,7 +25,7 @@ bool pb_decode_from_bytes(const uint8_t *srcbuf, size_t srcbufsize, const pb_msg
{
pb_istream_t stream = pb_istream_from_buffer(srcbuf, srcbufsize);
if (!pb_decode(&stream, fields, dest_struct)) {
LOG_ERROR("Can't decode protobuf reason='%s', pb_msgdesc 0x%p\n", PB_GET_ERROR(&stream), fields);
LOG_ERROR("Can't decode protobuf reason='%s', pb_msgdesc %p\n", PB_GET_ERROR(&stream), fields);
return false;
} else {
return true;

View File

@@ -27,7 +27,6 @@
#ifdef HAS_NCP5623
#include <graphics/RAKled.h>
NCP5623 rgb;
uint8_t red = 0;
uint8_t green = 0;

View File

@@ -31,7 +31,7 @@
#if defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040)
#include "modules/ExternalNotificationModule.h"
#include "modules/RangeTestModule.h"
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(CONFIG_IDF_TARGET_ESP32S2)
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040)) && !defined(CONFIG_IDF_TARGET_ESP32S2)
#include "modules/SerialModule.h"
#endif
#endif
@@ -60,9 +60,15 @@ void setupModules()
new ReplyModule();
#if HAS_BUTTON
rotaryEncoderInterruptImpl1 = new RotaryEncoderInterruptImpl1();
rotaryEncoderInterruptImpl1->init();
if (!rotaryEncoderInterruptImpl1->init()) {
delete rotaryEncoderInterruptImpl1;
rotaryEncoderInterruptImpl1 = nullptr;
}
upDownInterruptImpl1 = new UpDownInterruptImpl1();
upDownInterruptImpl1->init();
if (!upDownInterruptImpl1->init()) {
delete upDownInterruptImpl1;
upDownInterruptImpl1 = nullptr;
}
cardKbI2cImpl = new CardKbI2cImpl();
cardKbI2cImpl->init();
#ifdef INPUTBROKER_MATRIX_TYPE
@@ -86,7 +92,8 @@ void setupModules()
new AirQualityTelemetryModule();
}
#endif
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3)
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040)) && !defined(CONFIG_IDF_TARGET_ESP32S2) && \
!defined(CONFIG_IDF_TARGET_ESP32C3)
new SerialModule();
#endif
#ifdef ARCH_ESP32

View File

@@ -99,7 +99,6 @@ NeighborInfoModule::NeighborInfoModule()
setIntervalFromNow(35 * 1000);
} else {
LOG_DEBUG("NeighborInfoModule is disabled\n");
neighborState = meshtastic_NeighborInfo_init_zero;
disable();
}
}
@@ -203,8 +202,10 @@ Pass it to an upper client; do not persist this data on the mesh
*/
bool NeighborInfoModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_NeighborInfo *np)
{
printNeighborInfo("RECEIVED", np);
updateNeighbors(mp, np);
if (enabled) {
printNeighborInfo("RECEIVED", np);
updateNeighbors(mp, np);
}
// Allow others to handle this packet
return false;
}

View File

@@ -40,7 +40,9 @@ void NodeInfoModule::sendOurNodeInfo(NodeNum dest, bool wantReplies, uint8_t cha
meshtastic_MeshPacket *p = allocReply();
if (p) { // Check whether we didn't ignore it
p->to = dest;
p->decoded.want_response = wantReplies;
p->decoded.want_response = (config.device.role != meshtastic_Config_DeviceConfig_Role_TRACKER &&
config.device.role != meshtastic_Config_DeviceConfig_Role_SENSOR) &&
wantReplies;
p->priority = meshtastic_MeshPacket_Priority_BACKGROUND;
if (channel > 0) {
LOG_DEBUG("sending ourNodeInfo to channel %d\n", channel);

View File

@@ -1,4 +1,5 @@
#include "PositionModule.h"
#include "GPS.h"
#include "MeshService.h"
#include "NodeDB.h"
#include "RTC.h"
@@ -7,6 +8,8 @@
#include "airtime.h"
#include "configuration.h"
#include "gps/GeoCoord.h"
#include "sleep.h"
#include "target_specific.h"
PositionModule *positionModule;
@@ -14,8 +17,22 @@ PositionModule::PositionModule()
: ProtobufModule("position", meshtastic_PortNum_POSITION_APP, &meshtastic_Position_msg),
concurrency::OSThread("PositionModule")
{
isPromiscuous = true; // We always want to update our nodedb, even if we are sniffing on others
setIntervalFromNow(60 * 1000); // Send our initial position 60 seconds after we start (to give GPS time to setup)
isPromiscuous = true; // We always want to update our nodedb, even if we are sniffing on others
if (config.device.role != meshtastic_Config_DeviceConfig_Role_TRACKER)
setIntervalFromNow(60 * 1000);
// Power saving trackers should clear their position on startup to avoid waking up and sending a stale position
if (config.device.role == meshtastic_Config_DeviceConfig_Role_TRACKER && config.power.is_power_saving) {
clearPosition();
}
}
void PositionModule::clearPosition()
{
LOG_DEBUG("Clearing position on startup for sleepy tracker (ー。ー) zzz\n");
meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(nodeDB.getNodeNum());
node->position.latitude_i = 0;
node->position.longitude_i = 0;
}
bool PositionModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_Position *pptr)
@@ -33,12 +50,12 @@ bool PositionModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, mes
// return false;
}
// Log packet size and list of fields
LOG_INFO("POSITION node=%08x l=%d %s%s%s%s%s%s%s%s%s%s%s%s%s\n", getFrom(&mp), mp.decoded.payload.size,
p.latitude_i ? "LAT " : "", p.longitude_i ? "LON " : "", p.altitude ? "MSL " : "", p.altitude_hae ? "HAE " : "",
p.altitude_geoidal_separation ? "GEO " : "", p.PDOP ? "PDOP " : "", p.HDOP ? "HDOP " : "", p.VDOP ? "VDOP " : "",
p.sats_in_view ? "SIV " : "", p.fix_quality ? "FXQ " : "", p.fix_type ? "FXT " : "", p.timestamp ? "PTS " : "",
p.time ? "TIME " : "");
// Log packet size and data fields
LOG_INFO("POSITION node=%08x l=%d latI=%d lonI=%d msl=%d hae=%d geo=%d pdop=%d hdop=%d vdop=%d siv=%d fxq=%d fxt=%d pts=%d "
"time=%d\n",
getFrom(&mp), mp.decoded.payload.size, p.latitude_i, p.longitude_i, p.altitude, p.altitude_hae,
p.altitude_geoidal_separation, p.PDOP, p.HDOP, p.VDOP, p.sats_in_view, p.fix_quality, p.fix_type, p.timestamp,
p.time);
if (p.time) {
struct timeval tv;
@@ -148,7 +165,7 @@ void PositionModule::sendOurPosition(NodeNum dest, bool wantReplies, uint8_t cha
}
p->to = dest;
p->decoded.want_response = wantReplies;
p->decoded.want_response = config.device.role == meshtastic_Config_DeviceConfig_Role_TRACKER ? false : wantReplies;
if (config.device.role == meshtastic_Config_DeviceConfig_Role_TRACKER)
p->priority = meshtastic_MeshPacket_Priority_RELIABLE;
else
@@ -159,10 +176,23 @@ void PositionModule::sendOurPosition(NodeNum dest, bool wantReplies, uint8_t cha
p->channel = channel;
service.sendToMesh(p, RX_SRC_LOCAL, true);
if (config.device.role == meshtastic_Config_DeviceConfig_Role_TRACKER && config.power.is_power_saving) {
LOG_DEBUG("Starting next execution in 3 seconds and then going to sleep.\n");
sleepOnNextExecution = true;
setIntervalFromNow(3000);
}
}
int32_t PositionModule::runOnce()
{
if (sleepOnNextExecution == true) {
sleepOnNextExecution = false;
uint32_t nightyNightMs = getConfiguredOrDefaultMs(config.position.position_broadcast_secs);
LOG_DEBUG("Sleeping for %ims, then awaking to send position again.\n", nightyNightMs);
doDeepSleep(nightyNightMs, false);
}
meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(nodeDB.getNodeNum());
// We limit our GPS broadcasts to a max rate
@@ -172,7 +202,7 @@ int32_t PositionModule::runOnce()
if (lastGpsSend == 0 || msSinceLastSend >= intervalMs) {
// Only send packets if the channel is less than 40% utilized.
if (airTime->isTxAllowedChannelUtil()) {
if (airTime->isTxAllowedChannelUtil(config.device.role != meshtastic_Config_DeviceConfig_Role_TRACKER)) {
if (hasValidPosition(node)) {
lastGpsSend = now;
@@ -193,26 +223,19 @@ int32_t PositionModule::runOnce()
const meshtastic_NodeInfoLite *node2 = service.refreshLocalMeshNode(); // should guarantee there is now a position
if (hasValidPosition(node2)) {
// The minimum distance to travel before we are able to send a new position packet.
const uint32_t distanceTravelThreshold =
config.position.broadcast_smart_minimum_distance > 0 ? config.position.broadcast_smart_minimum_distance : 100;
// The minimum time (in seconds) that would pass before we are able to send a new position packet.
const uint32_t minimumTimeThreshold =
getConfiguredOrDefaultMs(config.position.broadcast_smart_minimum_interval_secs, 30);
// Determine the distance in meters between two points on the globe
float distanceTraveledSinceLastSend =
GeoCoord::latLongToMeter(lastGpsLatitude * 1e-7, lastGpsLongitude * 1e-7, node->position.latitude_i * 1e-7,
node->position.longitude_i * 1e-7);
auto smartPosition = getDistanceTraveledSinceLastSend(node->position);
if ((abs(distanceTraveledSinceLastSend) >= distanceTravelThreshold) && msSinceLastSend >= minimumTimeThreshold) {
if (smartPosition.hasTraveledOverThreshold && msSinceLastSend >= minimumTimeThreshold) {
bool requestReplies = currentGeneration != radioGeneration;
currentGeneration = radioGeneration;
LOG_INFO("Sending smart pos@%x:6 to mesh (distanceTraveled=%fm, minDistanceThreshold=%im, timeElapsed=%ims, "
"minTimeInterval=%ims)\n",
localPosition.timestamp, abs(distanceTraveledSinceLastSend), distanceTravelThreshold,
localPosition.timestamp, smartPosition.distanceTraveled, smartPosition.distanceThreshold,
msSinceLastSend, minimumTimeThreshold);
sendOurPosition(NODENUM_BROADCAST, requestReplies);
@@ -230,4 +253,48 @@ int32_t PositionModule::runOnce()
}
return 5000; // to save power only wake for our callback occasionally
}
struct SmartPosition PositionModule::getDistanceTraveledSinceLastSend(meshtastic_PositionLite currentPosition)
{
// The minimum distance to travel before we are able to send a new position packet.
const uint32_t distanceTravelThreshold = getConfiguredOrDefault(config.position.broadcast_smart_minimum_distance, 100);
// Determine the distance in meters between two points on the globe
float distanceTraveledSinceLastSend = GeoCoord::latLongToMeter(
lastGpsLatitude * 1e-7, lastGpsLongitude * 1e-7, currentPosition.latitude_i * 1e-7, currentPosition.longitude_i * 1e-7);
return SmartPosition{.distanceTraveled = abs(distanceTraveledSinceLastSend),
.distanceThreshold = distanceTravelThreshold,
.hasTraveledOverThreshold = abs(distanceTraveledSinceLastSend) >= distanceTravelThreshold};
}
void PositionModule::handleNewPosition()
{
meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(nodeDB.getNodeNum());
const meshtastic_NodeInfoLite *node2 = service.refreshLocalMeshNode(); // should guarantee there is now a position
// We limit our GPS broadcasts to a max rate
uint32_t now = millis();
uint32_t msSinceLastSend = now - lastGpsSend;
if (hasValidPosition(node2)) {
auto smartPosition = getDistanceTraveledSinceLastSend(node->position);
if (smartPosition.hasTraveledOverThreshold) {
bool requestReplies = currentGeneration != radioGeneration;
currentGeneration = radioGeneration;
LOG_INFO("Sending smart pos@%x:6 to mesh (distanceTraveled=%fm, minDistanceThreshold=%im, timeElapsed=%ims)\n",
localPosition.timestamp, smartPosition.distanceTraveled, smartPosition.distanceThreshold, msSinceLastSend);
sendOurPosition(NODENUM_BROADCAST, requestReplies);
// Set the current coords as our last ones, after we've compared distance with current and decided to send
lastGpsLatitude = node->position.latitude_i;
lastGpsLongitude = node->position.longitude_i;
/* Update lastGpsSend to now. This means if the device is stationary, then
getPref_position_broadcast_secs will still apply.
*/
lastGpsSend = now;
}
}
}

View File

@@ -31,6 +31,8 @@ class PositionModule : public ProtobufModule<meshtastic_Position>, private concu
*/
void sendOurPosition(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false, uint8_t channel = 0);
void handleNewPosition();
protected:
/** Called to handle a particular incoming message
@@ -44,6 +46,18 @@ class PositionModule : public ProtobufModule<meshtastic_Position>, private concu
/** Does our periodic broadcast */
virtual int32_t runOnce() override;
private:
struct SmartPosition getDistanceTraveledSinceLastSend(meshtastic_PositionLite currentPosition);
/** Only used in power saving trackers for now */
void clearPosition();
};
extern PositionModule *positionModule;
struct SmartPosition {
float distanceTraveled;
uint32_t distanceThreshold;
bool hasTraveledOverThreshold;
};
extern PositionModule *positionModule;

View File

@@ -44,9 +44,10 @@
*/
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3)
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040)) && !defined(CONFIG_IDF_TARGET_ESP32S2) && \
!defined(CONFIG_IDF_TARGET_ESP32C3)
#define RX_BUFFER 128
#define RX_BUFFER 256
#define TIMEOUT 250
#define BAUD 38400
#define ACK 1
@@ -141,7 +142,12 @@ int32_t SerialModule::runOnce()
}
#elif !defined(TTGO_T_ECHO)
if (moduleConfig.serial.rxd && moduleConfig.serial.txd) {
#ifdef ARCH_RP2040
Serial2.setFIFOSize(RX_BUFFER);
Serial2.setPinout(moduleConfig.serial.txd, moduleConfig.serial.rxd);
#else
Serial2.setPins(moduleConfig.serial.rxd, moduleConfig.serial.txd);
#endif
Serial2.begin(baud, SERIAL_8N1);
Serial2.setTimeout(moduleConfig.serial.timeout > 0 ? moduleConfig.serial.timeout : TIMEOUT);
} else {
@@ -182,7 +188,7 @@ int32_t SerialModule::runOnce()
}
}
}
#ifndef TTGO_T_ECHO
#if !defined(TTGO_T_ECHO)
else {
while (Serial2.available()) {
serialPayloadSize = Serial2.readBytes(serialBytes, meshtastic_Constants_DATA_PAYLOAD_LEN);

View File

@@ -8,7 +8,8 @@
#include <Arduino.h>
#include <functional>
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3)
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040)) && !defined(CONFIG_IDF_TARGET_ESP32S2) && \
!defined(CONFIG_IDF_TARGET_ESP32C3)
class SerialModule : public StreamAPI, private concurrency::OSThread
{
@@ -74,4 +75,4 @@ class SerialModuleRadio : public MeshModule
extern SerialModuleRadio *serialModuleRadio;
#endif
#endif

View File

@@ -455,6 +455,13 @@ void MQTT::onSend(const meshtastic_MeshPacket &mp, ChannelIndex chIndex)
{
auto &ch = channels.getByIndex(chIndex);
if (&mp.decoded && strcmp(moduleConfig.mqtt.address, default_mqtt_address) == 0 &&
(mp.decoded.portnum == meshtastic_PortNum_RANGE_TEST_APP ||
mp.decoded.portnum == meshtastic_PortNum_DETECTION_SENSOR_APP)) {
LOG_DEBUG("MQTT onSend - Ignoring range test or detection sensor message on public mqtt\n");
return;
}
if (ch.settings.uplink_enabled) {
const char *channelId = channels.getGlobalId(chIndex); // FIXME, for now we just use the human name for the channel
@@ -509,34 +516,34 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp)
JSONObject msgPayload;
JSONObject jsonObj;
switch (mp->decoded.portnum) {
case meshtastic_PortNum_TEXT_MESSAGE_APP: {
msgType = "text";
// convert bytes to string
LOG_DEBUG("got text message of size %u\n", mp->decoded.payload.size);
char payloadStr[(mp->decoded.payload.size) + 1];
memcpy(payloadStr, mp->decoded.payload.bytes, mp->decoded.payload.size);
payloadStr[mp->decoded.payload.size] = 0; // null terminated string
// check if this is a JSON payload
JSONValue *json_value = JSON::Parse(payloadStr);
if (json_value != NULL) {
LOG_INFO("text message payload is of type json\n");
// if it is, then we can just use the json object
jsonObj["payload"] = json_value;
} else {
// if it isn't, then we need to create a json object
// with the string as the value
LOG_INFO("text message payload is of type plaintext\n");
msgPayload["text"] = new JSONValue(payloadStr);
jsonObj["payload"] = new JSONValue(msgPayload);
if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
switch (mp->decoded.portnum) {
case meshtastic_PortNum_TEXT_MESSAGE_APP: {
msgType = "text";
// convert bytes to string
LOG_DEBUG("got text message of size %u\n", mp->decoded.payload.size);
char payloadStr[(mp->decoded.payload.size) + 1];
memcpy(payloadStr, mp->decoded.payload.bytes, mp->decoded.payload.size);
payloadStr[mp->decoded.payload.size] = 0; // null terminated string
// check if this is a JSON payload
JSONValue *json_value = JSON::Parse(payloadStr);
if (json_value != NULL) {
LOG_INFO("text message payload is of type json\n");
// if it is, then we can just use the json object
jsonObj["payload"] = json_value;
} else {
// if it isn't, then we need to create a json object
// with the string as the value
LOG_INFO("text message payload is of type plaintext\n");
msgPayload["text"] = new JSONValue(payloadStr);
jsonObj["payload"] = new JSONValue(msgPayload);
}
break;
}
break;
}
case meshtastic_PortNum_TELEMETRY_APP: {
msgType = "telemetry";
meshtastic_Telemetry scratch;
meshtastic_Telemetry *decoded = NULL;
if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
case meshtastic_PortNum_TELEMETRY_APP: {
msgType = "telemetry";
meshtastic_Telemetry scratch;
meshtastic_Telemetry *decoded = NULL;
memset(&scratch, 0, sizeof(scratch));
if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_Telemetry_msg, &scratch)) {
decoded = &scratch;
@@ -557,14 +564,12 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp)
} else {
LOG_ERROR("Error decoding protobuf for telemetry message!\n");
}
};
break;
}
case meshtastic_PortNum_NODEINFO_APP: {
msgType = "nodeinfo";
meshtastic_User scratch;
meshtastic_User *decoded = NULL;
if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
break;
}
case meshtastic_PortNum_NODEINFO_APP: {
msgType = "nodeinfo";
meshtastic_User scratch;
meshtastic_User *decoded = NULL;
memset(&scratch, 0, sizeof(scratch));
if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_User_msg, &scratch)) {
decoded = &scratch;
@@ -576,14 +581,12 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp)
} else {
LOG_ERROR("Error decoding protobuf for nodeinfo message!\n");
}
};
break;
}
case meshtastic_PortNum_POSITION_APP: {
msgType = "position";
meshtastic_Position scratch;
meshtastic_Position *decoded = NULL;
if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
break;
}
case meshtastic_PortNum_POSITION_APP: {
msgType = "position";
meshtastic_Position scratch;
meshtastic_Position *decoded = NULL;
memset(&scratch, 0, sizeof(scratch));
if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_Position_msg, &scratch)) {
decoded = &scratch;
@@ -620,15 +623,12 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp)
} else {
LOG_ERROR("Error decoding protobuf for position message!\n");
}
};
break;
}
case meshtastic_PortNum_WAYPOINT_APP: {
msgType = "position";
meshtastic_Waypoint scratch;
meshtastic_Waypoint *decoded = NULL;
if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
break;
}
case meshtastic_PortNum_WAYPOINT_APP: {
msgType = "position";
meshtastic_Waypoint scratch;
meshtastic_Waypoint *decoded = NULL;
memset(&scratch, 0, sizeof(scratch));
if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_Waypoint_msg, &scratch)) {
decoded = &scratch;
@@ -643,14 +643,12 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp)
} else {
LOG_ERROR("Error decoding protobuf for position message!\n");
}
};
break;
}
case meshtastic_PortNum_NEIGHBORINFO_APP: {
msgType = "neighborinfo";
meshtastic_NeighborInfo scratch;
meshtastic_NeighborInfo *decoded = NULL;
if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
break;
}
case meshtastic_PortNum_NEIGHBORINFO_APP: {
msgType = "neighborinfo";
meshtastic_NeighborInfo scratch;
meshtastic_NeighborInfo *decoded = NULL;
memset(&scratch, 0, sizeof(scratch));
if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_NeighborInfo_msg,
&scratch)) {
@@ -671,12 +669,14 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp)
} else {
LOG_ERROR("Error decoding protobuf for neighborinfo message!\n");
}
};
break;
}
// add more packet types here if needed
default:
break;
break;
}
// add more packet types here if needed
default:
break;
}
} else {
LOG_WARN("Couldn't convert encrypted payload of MeshPacket to JSON\n");
}
jsonObj["id"] = new JSONValue((uint)mp->id);

View File

@@ -123,22 +123,6 @@
#define HW_VENDOR meshtastic_HardwareModel_HELTEC_HT62
#endif
//
// Standard definitions for ESP32 targets
//
#define GPS_SERIAL_NUM 1
#ifndef GPS_RX_PIN
#define GPS_RX_PIN 34
#endif
#ifndef GPS_TX_PIN
#ifdef USE_JTAG
#define GPS_TX_PIN -1
#else
#define GPS_TX_PIN 12
#endif
#endif
// -----------------------------------------------------------------------------
// LoRa SPI
// -----------------------------------------------------------------------------
@@ -151,4 +135,4 @@
#define RF95_NSS 18
#endif
#define SERIAL0_RX_GPIO 3 // Always GPIO3 on ESP32
#define SERIAL0_RX_GPIO 3 // Always GPIO3 on ESP32

View File

@@ -193,16 +193,12 @@ void cpuDeepSleep(uint32_t msecToWake)
rtc_gpio_isolate((gpio_num_t)rtcGpios[i]);
#endif
// FIXME, disable internal rtc pullups/pulldowns on the non isolated pins. for inputs that we aren't using
// to detect wake and in normal operation the external part drives them hard.
// We want RTC peripherals to stay on
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
// FIXME, disable internal rtc pullups/pulldowns on the non isolated pins. for inputs that we aren't using
// to detect wake and in normal operation the external part drives them hard.
#ifdef BUTTON_PIN
// Only GPIOs which are have RTC functionality can be used in this bit map: 0,2,4,12-15,25-27,32-39.
// Only GPIOs which are have RTC functionality can be used in this bit map: 0,2,4,12-15,25-27,32-39.
#if SOC_RTCIO_HOLD_SUPPORTED
uint64_t gpioMask = (1ULL << config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN);
uint64_t gpioMask = (1ULL << (config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN));
#endif
#ifdef BUTTON_NEED_PULLUP
@@ -218,6 +214,9 @@ void cpuDeepSleep(uint32_t msecToWake)
#endif
#endif
// We want RTC peripherals to stay on
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
esp_sleep_enable_timer_wakeup(msecToWake * 1000ULL); // call expects usecs
esp_deep_sleep_start(); // TBD mA sleep current (battery)
}

View File

@@ -184,10 +184,16 @@ void cpuDeepSleep(uint32_t msecToWake)
// FIXME, use non-init RAM per
// https://devzone.nordicsemi.com/f/nordic-q-a/48919/ram-retention-settings-with-softdevice-enabled
auto ok = sd_power_system_off();
if (ok != NRF_SUCCESS) {
LOG_ERROR("FIXME: Ignoring soft device (EasyDMA pending?) and forcing system-off!\n");
NRF_POWER->SYSTEMOFF = 1;
if (config.device.role == meshtastic_Config_DeviceConfig_Role_TRACKER && config.power.is_power_saving == true) {
sd_power_mode_set(NRF_POWER_MODE_LOWPWR);
delay(msecToWake);
NVIC_SystemReset();
} else {
auto ok = sd_power_system_off();
if (ok != NRF_SUCCESS) {
LOG_ERROR("FIXME: Ignoring soft device (EasyDMA pending?) and forcing system-off!\n");
NRF_POWER->SYSTEMOFF = 1;
}
}
// The following code should not be run, because we are off

View File

@@ -90,39 +90,34 @@ void setLed(bool ledOn)
#endif
}
void setGPSPower(bool on)
{
LOG_INFO("Setting GPS power=%d\n", on);
#ifdef PIN_GPS_EN
digitalWrite(PIN_GPS_EN, on ? 1 : 0);
#endif
#ifdef HAS_PMU
if (pmu_found && PMU) {
uint8_t model = PMU->getChipModel();
if (model == XPOWERS_AXP2101) {
if (HW_VENDOR == meshtastic_HardwareModel_TBEAM) {
// t-beam v1.2 GNSS power channel
on ? PMU->enablePowerOutput(XPOWERS_ALDO3) : PMU->disablePowerOutput(XPOWERS_ALDO3);
} else if (HW_VENDOR == meshtastic_HardwareModel_LILYGO_TBEAM_S3_CORE) {
// t-beam-s3-core GNSS power channel
on ? PMU->enablePowerOutput(XPOWERS_ALDO4) : PMU->disablePowerOutput(XPOWERS_ALDO4);
}
} else if (model == XPOWERS_AXP192) {
// t-beam v1.1 GNSS power channel
on ? PMU->enablePowerOutput(XPOWERS_LDO3) : PMU->disablePowerOutput(XPOWERS_LDO3);
}
}
#endif
}
// Perform power on init that we do on each wake from deep sleep
void initDeepSleep()
{
#ifdef ARCH_ESP32
bootCount++;
const char *reason;
wakeCause = esp_sleep_get_wakeup_cause();
switch (wakeCause) {
case ESP_SLEEP_WAKEUP_EXT0:
reason = "ext0 RTC_IO";
break;
case ESP_SLEEP_WAKEUP_EXT1:
reason = "ext1 RTC_CNTL";
break;
case ESP_SLEEP_WAKEUP_TIMER:
reason = "timer";
break;
case ESP_SLEEP_WAKEUP_TOUCHPAD:
reason = "touchpad";
break;
case ESP_SLEEP_WAKEUP_ULP:
reason = "ULP program";
break;
default:
reason = "reset";
break;
}
/*
Not using yet because we are using wake on all buttons being low
@@ -133,7 +128,6 @@ void initDeepSleep()
#ifdef DEBUG_PORT
// If we booted because our timer ran out or the user pressed reset, send those as fake events
const char *reason = "reset"; // our best guess
RESET_REASON hwReason = rtc_get_reset_reason(0);
if (hwReason == RTCWDT_BROWN_OUT_RESET)
@@ -145,9 +139,6 @@ void initDeepSleep()
if (hwReason == TG1WDT_SYS_RESET)
reason = "intWatchdog";
if (wakeCause == ESP_SLEEP_WAKEUP_TIMER)
reason = "timeout";
LOG_INFO("Booted, wake cause %d (boot count %d), reset_reason=%s\n", wakeCause, bootCount, reason);
#endif
#endif
@@ -162,16 +153,18 @@ bool doPreflightSleep()
}
/// Tell devices we are going to sleep and wait for them to handle things
static void waitEnterSleep()
static void waitEnterSleep(bool skipPreflight = false)
{
uint32_t now = millis();
while (!doPreflightSleep()) {
delay(100); // Kinda yucky - wait until radio says say we can shutdown (finished in process sends/receives)
if (!skipPreflight) {
uint32_t now = millis();
while (!doPreflightSleep()) {
delay(100); // Kinda yucky - wait until radio says say we can shutdown (finished in process sends/receives)
if (millis() - now > 30 * 1000) { // If we wait too long just report an error and go to sleep
RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_SLEEP_ENTER_WAIT);
assert(0); // FIXME - for now we just restart, need to fix bug #167
break;
if (millis() - now > 30 * 1000) { // If we wait too long just report an error and go to sleep
RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_SLEEP_ENTER_WAIT);
assert(0); // FIXME - for now we just restart, need to fix bug #167
break;
}
}
}
@@ -182,31 +175,7 @@ static void waitEnterSleep()
notifySleep.notifyObservers(NULL);
}
void doGPSpowersave(bool on)
{
#if defined(HAS_PMU) || defined(PIN_GPS_EN)
if (on) {
LOG_INFO("Turning GPS back on\n");
gps->forceWake(1);
setGPSPower(1);
} else {
LOG_INFO("Turning off GPS chip\n");
notifyGPSSleep.notifyObservers(NULL);
setGPSPower(0);
}
#endif
#ifdef PIN_GPS_WAKE
if (on) {
LOG_INFO("Waking GPS");
gps->forceWake(1);
} else {
LOG_INFO("GPS entering sleep");
notifyGPSSleep.notifyObservers(NULL);
}
#endif
}
void doDeepSleep(uint32_t msecToWake)
void doDeepSleep(uint32_t msecToWake, bool skipPreflight = false)
{
if (INCLUDE_vTaskSuspend && (msecToWake == portMAX_DELAY)) {
LOG_INFO("Entering deep sleep forever\n");
@@ -216,7 +185,7 @@ void doDeepSleep(uint32_t msecToWake)
// not using wifi yet, but once we are this is needed to shutoff the radio hw
// esp_wifi_stop();
waitEnterSleep();
waitEnterSleep(skipPreflight);
notifyDeepSleep.notifyObservers(NULL);
screen->doDeepSleep(); // datasheet says this will draw only 10ua
@@ -224,7 +193,8 @@ void doDeepSleep(uint32_t msecToWake)
nodeDB.saveToDisk();
// Kill GPS power completely (even if previously we just had it in sleep mode)
setGPSPower(false);
if (gps)
gps->setGPSPower(false, false, 0);
setLed(false);
@@ -278,7 +248,7 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r
{
// LOG_DEBUG("Enter light sleep\n");
waitEnterSleep();
waitEnterSleep(false);
uint64_t sleepUsec = sleepMsec * 1000LL;

View File

@@ -4,7 +4,7 @@
#include "Observer.h"
#include "configuration.h"
void doDeepSleep(uint32_t msecToWake), cpuDeepSleep(uint32_t msecToWake);
void doDeepSleep(uint32_t msecToWake, bool skipPreflight), cpuDeepSleep(uint32_t msecToWake);
#ifdef ARCH_ESP32
#include "esp_sleep.h"
@@ -18,8 +18,6 @@ extern esp_sleep_source_t wakeCause;
extern XPowersLibInterface *PMU;
#endif
void setGPSPower(bool on);
void doGPSpowersave(bool on);
// Perform power on init that we do on each wake from deep sleep
void initDeepSleep();

View File

@@ -47,12 +47,12 @@ extern "C" {
#define PIN_LED2 (0 + 6) // Built in Green P0.06
// Green Built in LED1
//#define PIN_LED1 (0 + 6) // LED1 P1.15
// #define PIN_LED1 (0 + 6) // LED1 P1.15
// RGB NeoPixel LED2
//#define PIN_LED1 (0 + 8) Red
//#define PIN_LED1 (32 + 9) Green
//#define PIN_LED1 (0 + 12) Blue
// #define PIN_LED1 (0 + 8) Red
// #define PIN_LED1 (32 + 9) Green
// #define PIN_LED1 (0 + 12) Blue
#define LED_BUILTIN PIN_LED1
#define LED_CONN PIN_LED2
@@ -113,7 +113,7 @@ static const uint8_t SCK = PIN_SPI_SCK;
* eink display pins
*/
//#define PIN_EINK_EN (-1)
// #define PIN_EINK_EN (-1)
#define PIN_EINK_EN (0 + 6) // Turn on the Green built in LED
#define PIN_EINK_CS (32) // EPD_CS
#define PIN_EINK_BUSY (20) // EPD_BUSY
@@ -140,7 +140,8 @@ static const uint8_t SCK = PIN_SPI_SCK;
#define SX126X_RESET (32 + 15) // LORA_RESET P1.15
#define SX126X_TXEN (32 + 13) // TXEN P1.13 NiceRF 868 dont use
#define SX126X_RXEN (32 + 10) // RXEN P1.10 NiceRF 868 dont use
#define SX126X_E22
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
#define PIN_GPS_EN (-1)
#define PIN_GPS_PPS (-1) // Pulse per second input from the GPS

View File

@@ -73,7 +73,7 @@ static const uint8_t AREF = PIN_AREF;
*/
#define SPI_INTERFACES_COUNT 2
// here
//#define SPI_INTERFACES_COUNT 1
// #define SPI_INTERFACES_COUNT 1
#define PIN_SPI_MISO (0 + 31) // MISO P0.31
#define PIN_SPI_MOSI (0 + 30) // MOSI P0.30
@@ -94,7 +94,7 @@ static const uint8_t SCK = PIN_SPI_SCK;
* eink display pins
*/
//#define PIN_EINK_EN (-1)
// #define PIN_EINK_EN (-1)
#define PIN_EINK_CS (0 + 3) // EPD_CS
#define PIN_EINK_BUSY (32 + 11) // EPD_BUSY
#define PIN_EINK_DC (32 + 13) // EPD_D/C
@@ -118,8 +118,8 @@ static const uint8_t SCK = PIN_SPI_SCK;
#define SX128X_CS (0 + 23)
#define SX128X_DIO1 (0 + 4)
#define SX128X_BUSY (0 + 7)
//#define SX128X_TXEN (32 + 9)
//#define SX128X_RXEN (0 + 12)
// #define SX128X_TXEN (32 + 9)
// #define SX128X_RXEN (0 + 12)
#define SX128X_RESET LORA_RESET
#define PIN_GPS_EN (-1)

View File

@@ -96,8 +96,8 @@ static const uint8_t SCK = PIN_SPI_SCK;
#define SX128X_CS (0 + 23)
#define SX128X_DIO1 (0 + 4)
#define SX128X_BUSY (0 + 7)
//#define SX128X_TXEN (32 + 9)
//#define SX128X_RXEN (0 + 12)
// #define SX128X_TXEN (32 + 9)
// #define SX128X_RXEN (0 + 12)
#define SX128X_RESET LORA_RESET
#define PIN_GPS_EN (-1)

View File

@@ -23,7 +23,9 @@
#define SX126X_DIO1 LORA_DIO1
#define SX126X_BUSY 10
#define SX126X_RESET LORA_RESET
#define SX126X_E22 // use DIO2 as RF switch
#define SX126X_DIO2_AS_RF_SWITCH // use DIO2 as RF switch
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
#define HAS_GPS 0
#undef GPS_RX_PIN

View File

@@ -27,11 +27,11 @@ static const uint8_t SCK = 21;
static const uint8_t MOSI = 38;
static const uint8_t SS = 17;
//#define SPI_MOSI (11)
//#define SPI_SCK (14)
//#define SPI_MISO (2)
//#define SPI_CS (13)
// #define SPI_MOSI (11)
// #define SPI_SCK (14)
// #define SPI_MISO (2)
// #define SPI_CS (13)
//#define SDCARD_CS SPI_CS
// #define SDCARD_CS SPI_CS
#endif /* Pins_Arduino_h */
#endif /* Pins_Arduino_h */

View File

@@ -2,10 +2,10 @@
#undef GPS_RX_PIN
#undef GPS_TX_PIN
//#define HAS_SCREEN 0
// #define HAS_SCREEN 0
//#define HAS_SDCARD
//#define SDCARD_USE_SPI1
// #define HAS_SDCARD
// #define SDCARD_USE_SPI1
#define USE_SSD1306
#define I2C_SDA 12
@@ -14,13 +14,13 @@
#define LED_PIN 46
#define LED_STATE_ON 0 // State when LED is litted
//#define BUTTON_PIN 15 // Pico OLED 1.3 User key 0 - removed User key 1 (17)
// #define BUTTON_PIN 15 // Pico OLED 1.3 User key 0 - removed User key 1 (17)
#define BUTTON_PIN 40
//#define BUTTON_PIN 0 // This is the BOOT button pad at the moment
//#define BUTTON_NEED_PULLUP
// #define BUTTON_PIN 0 // This is the BOOT button pad at the moment
// #define BUTTON_NEED_PULLUP
//#define USE_RF95 // RFM95/SX127x
// #define USE_RF95 // RFM95/SX127x
#undef RF95_SCK
#undef RF95_MISO
@@ -43,10 +43,11 @@
#define SX126X_DIO1 LORA_DIO1
#define SX126X_BUSY LORA_BUSY
#define SX126X_RESET LORA_RESET
#define SX126X_E22
#define SX126X_DIO2_AS_RF_SWITCH
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
#endif
//#define USE_SX1280
// #define USE_SX1280
#ifdef USE_SX1280
#define RF95_MISO 1
#define RF95_SCK 3
@@ -61,13 +62,13 @@
#define SX128X_RESET LORA_RESET
#endif
//#define USE_EINK
// #define USE_EINK
/*
* eink display pins
*/
//#define PIN_EINK_CS
//#define PIN_EINK_BUSY
//#define PIN_EINK_DC
//#define PIN_EINK_RES (-1)
//#define PIN_EINK_SCLK 3
//#define PIN_EINK_MOSI 4
// #define PIN_EINK_CS
// #define PIN_EINK_BUSY
// #define PIN_EINK_DC
// #define PIN_EINK_RES (-1)
// #define PIN_EINK_SCLK 3
// #define PIN_EINK_MOSI 4

View File

@@ -31,10 +31,13 @@
// PINS FOR THE 900M22S
#define LORA_DIO1 26 // IRQ for SX1262/SX1268
#define LORA_DIO2 22 // BUSY for SX1262/SX1268
#define LORA_TXEN NOT_A_PIN // Input - RF switch TX control, connecting external MCU IO or DIO2, valid in high level
#define LORA_RXEN 17 // Input - RF switch RX control, connecting external MCU IO, valid in high level
#define LORA_DIO1 26 // IRQ for SX1262/SX1268
#define LORA_DIO2 22 // BUSY for SX1262/SX1268
// NOT_A_PIN is treated as RADIOLIB_NC due to how they are defined, best to use RADIOLIB_NC directly
#define LORA_TXEN RADIOLIB_NC // Input - RF switch TX control, connecting external MCU IO or DIO2, valid in high level
// E22_TXEN_CONNECTED_TO_DIO2 wasn't defined, so RXEN wasn't controlled. Commented it out to maintain behavior, but shouldn't be.
// Need to comment out defining SX126X_RXEN as LORA_RXEN too
// #define LORA_RXEN 17 // Input - RF switch RX control, connecting external MCU IO, valid in high level
#undef RF95_NSS
#define RF95_NSS 16
#define SX126X_BUSY 22
@@ -53,7 +56,7 @@
*/
// RX/TX for RFM95/SX127x
#define RF95_RXEN LORA_RXEN
// #define RF95_RXEN LORA_RXEN
#define RF95_TXEN LORA_TXEN
// #define RF95_TCXO <GPIO#>
@@ -61,12 +64,13 @@
#define SX126X_DIO1 LORA_DIO1
#define SX126X_RESET LORA_RESET
#define SX126X_RXEN LORA_RXEN
// #define SX126X_RXEN LORA_RXEN
#define SX126X_TXEN LORA_TXEN
// supported modules list
//#define USE_RF95 // RFM95/SX127x
// #define USE_RF95 // RFM95/SX127x
#define USE_SX1262
//#define USE_SX1268
//#define USE_LLCC68
#define SX126X_E22
// #define USE_SX1268
// #define USE_LLCC68
#define SX126X_DIO2_AS_RF_SWITCH
#define SX126X_DIO3_TCXO_VOLTAGE 1.8

View File

@@ -37,8 +37,9 @@
#define SX126X_RESET LORA_RESET
#define SX126X_RXEN 14
#define SX126X_TXEN RADIOLIB_NC
#define E22_TXEN_CONNECTED_TO_DIO2 1
#define SX126X_DIO2_AS_RF_SWITCH
// Set lora.tx_power to 13 for Hydra or other E22 900M30S target due to PA
#define SX126X_MAX_POWER 13
#define SX126X_E22
#define SX126X_DIO3_TCXO_VOLTAGE 1.8

View File

@@ -52,5 +52,5 @@
#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
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
#endif

View File

@@ -53,5 +53,5 @@
#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
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
#endif

View File

@@ -105,7 +105,7 @@ extern "C" {
#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
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
#endif
#ifdef __cplusplus

View File

@@ -33,4 +33,5 @@
#define SX126X_DIO1 LORA_DIO1
#define SX126X_BUSY LORA_BUSY
#define SX126X_RESET LORA_RESET
#define SX126X_E22
#define SX126X_DIO2_AS_RF_SWITCH
#define SX126X_DIO3_TCXO_VOLTAGE 1.8

View File

@@ -11,8 +11,6 @@
#define VEXT_ENABLE Vext // active low, powers the oled display and the lora antenna boost
#define BUTTON_PIN 0
#define PIN_GPS_EN 46 // GPS power enable pin
#define BATTERY_PIN 1 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
#define ADC_CHANNEL ADC1_GPIO1_CHANNEL
#define ADC_ATTENUATION ADC_ATTEN_DB_2_5 // lower dB for high resistance voltage divider
@@ -35,4 +33,6 @@
#define SX126X_DIO1 LORA_DIO1
#define SX126X_BUSY LORA_DIO2
#define SX126X_RESET LORA_RESET
#define SX126X_E22
#define SX126X_DIO2_AS_RF_SWITCH
#define SX126X_DIO3_TCXO_VOLTAGE 1.8

View File

@@ -40,4 +40,6 @@
#define SX126X_DIO1 LORA_DIO1
#define SX126X_BUSY LORA_DIO2
#define SX126X_RESET LORA_RESET
#define SX126X_E22
#define SX126X_DIO2_AS_RF_SWITCH
#define SX126X_DIO3_TCXO_VOLTAGE 1.8

View File

@@ -5,6 +5,7 @@ upload_protocol = esp-builtin
build_flags =
${esp32s3_base.build_flags} -I variants/heltec_wireless_tracker
-DGPS_POWER_TOGGLE
lib_deps =
${esp32s3_base.lib_deps}

View File

@@ -38,6 +38,8 @@
#define PIN_GPS_RESET 35
#define PIN_GPS_PPS 36
#define VGNSS_CTRL 37 // Heltec Tracker needs this pulled low for GPS
#define PIN_GPS_EN VGNSS_CTRL
#define GPS_EN_ACTIVE LOW
#define GPS_RESET_MODE LOW
#define GPS_UC6580
@@ -57,4 +59,6 @@
#define SX126X_DIO1 LORA_DIO1
#define SX126X_BUSY LORA_DIO2
#define SX126X_RESET LORA_RESET
#define SX126X_E22
#define SX126X_DIO2_AS_RF_SWITCH
#define SX126X_DIO3_TCXO_VOLTAGE 1.8

View File

@@ -32,4 +32,6 @@
#define SX126X_DIO1 LORA_DIO1
#define SX126X_BUSY LORA_DIO2
#define SX126X_RESET LORA_RESET
#define SX126X_E22
#define SX126X_DIO2_AS_RF_SWITCH
#define SX126X_DIO3_TCXO_VOLTAGE 1.8

View File

@@ -28,7 +28,7 @@
#define USE_LFXO
//#define USE_SEGGER
// #define USE_SEGGER
// Number of pins defined in PinDescription array
#define PINS_COUNT (16)
@@ -88,6 +88,7 @@
#define BATTERY_PIN 3
#define ADC_MULTIPLIER 1.436
#define SX126X_E22 // Not really an E22 but this board clones using DIO3 for tcxo control
#define SX126X_DIO2_AS_RF_SWITCH
#define SX126X_DIO3_TCXO_VOLTAGE 1.8 // Not really an E22 but this board clones using DIO3 for tcxo control
#endif

View File

@@ -134,7 +134,8 @@ static const uint8_t SCK = PIN_SPI_SCK;
#define SX126X_TXEN (31)
#define SX126X_POWER_EN \
(15) // FIXME, see warning hre https://github.com/BigCorvus/SX1262-LoRa-BLE-Relay/blob/master/LORA_RELAY_NRF52840.ino
#define SX126X_E22 // Indicates this SX1262 is inside of an ebyte E22 module and special config should be done for that
// Indicates this SX1262 is inside of an ebyte E22 module and special config should be done for that
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
#define ST7735_RESET (11) // Output
#define ST7735_CS (12)

View File

@@ -154,7 +154,8 @@ static const uint8_t SCK = PIN_SPI_SCK;
#define SX126X_TXEN (31)
#define SX126X_POWER_EN \
(15) // FIXME, see warning hre https://github.com/BigCorvus/SX1262-LoRa-BLE-Relay/blob/master/LORA_RELAY_NRF52840.ino
#define SX126X_E22 // Indicates this SX1262 is inside of an ebyte E22 module and special config should be done for that
// Indicates this SX1262 is inside of an ebyte E22 module and special config should be done for that
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
// ST7565 SPI
#define ST7735_RESET (11) // Output
@@ -164,8 +165,8 @@ static const uint8_t SCK = PIN_SPI_SCK;
#define ST7735_SDA (39) // actually spi MOSI
#define ST7735_SCK (37) // actually spi clk
#define PIN_GPS_WAKE 36 // Just kill GPS power when we want it to sleep? FIXME
#define GPS_WAKE_ACTIVE 0 // GPS Power output is active low
#define PIN_GPS_EN 36 // Just kill GPS power when we want it to sleep? FIXME
#define GPS_EN_ACTIVE 0 // GPS Power output is active low
// #define LORA_DISABLE_SENDING // The board can brownout during lora TX if you don't have a battery connected. Disable sending
// to allow USB power only based debugging

View File

@@ -4,7 +4,7 @@
#define BUTTON_PIN 3 // M5Stack STAMP C3 built in button
#define BUTTON_NEED_PULLUP
//#define HAS_SCREEN 0
// #define HAS_SCREEN 0
#define HAS_GPS 0
#undef GPS_RX_PIN
#undef GPS_TX_PIN
@@ -28,45 +28,46 @@
// WaveShare Core1262-868M OK
// https://www.waveshare.com/wiki/Core1262-868M
//#define USE_SX1262
//#define RF95_SCK 4
//#define RF95_MISO 5
//#define RF95_MOSI 6
//#define RF95_NSS 7
//#define LORA_DIO0 RADIOLIB_NC
//#define LORA_RESET 8
//#define LORA_DIO1 10
//#define LORA_DIO2 RADIOLIB_NC
//#define LORA_BUSY 18
//#define SX126X_CS RF95_NSS
//#define SX126X_DIO1 LORA_DIO1
//#define SX126X_BUSY LORA_BUSY
//#define SX126X_RESET LORA_RESET
//#define SX126X_E22
// #define USE_SX1262
// #define RF95_SCK 4
// #define RF95_MISO 5
// #define RF95_MOSI 6
// #define RF95_NSS 7
// #define LORA_DIO0 RADIOLIB_NC
// #define LORA_RESET 8
// #define LORA_DIO1 10
// #define LORA_DIO2 RADIOLIB_NC
// #define LORA_BUSY 18
// #define SX126X_CS RF95_NSS
// #define SX126X_DIO1 LORA_DIO1
// #define SX126X_BUSY LORA_BUSY
// #define SX126X_RESET LORA_RESET
// #define SX126X_DIO2_AS_RF_SWITCH
// #define SX126X_DIO3_TCXO_VOLTAGE 1.8
// SX128X 2.4 Ghz LoRa module Not OK - RadioLib issue ? still to confirm
//#define USE_SX1280
//#define RF95_SCK 4
//#define RF95_MISO 5
//#define RF95_MOSI 6
//#define RF95_NSS 7
//#define LORA_DIO0 -1
//#define LORA_DIO1 10
//#define LORA_DIO2 21
//#define LORA_RESET 8
//#define LORA_BUSY 1
//#define SX128X_CS RF95_NSS
//#define SX128X_DIO1 LORA_DIO1
//#define SX128X_BUSY LORA_BUSY
//#define SX128X_RESET LORA_RESET
//#define SX128X_MAX_POWER 10
// #define USE_SX1280
// #define RF95_SCK 4
// #define RF95_MISO 5
// #define RF95_MOSI 6
// #define RF95_NSS 7
// #define LORA_DIO0 -1
// #define LORA_DIO1 10
// #define LORA_DIO2 21
// #define LORA_RESET 8
// #define LORA_BUSY 1
// #define SX128X_CS RF95_NSS
// #define SX128X_DIO1 LORA_DIO1
// #define SX128X_BUSY LORA_BUSY
// #define SX128X_RESET LORA_RESET
// #define SX128X_MAX_POWER 10
// Not yet tested
//#define USE_EINK
//#define PIN_EINK_EN -1 // N/C
//#define PIN_EINK_CS 9 // EPD_CS
//#define PIN_EINK_BUSY 18 // EPD_BUSY
//#define PIN_EINK_DC 19 // EPD_D/C
//#define PIN_EINK_RES -1 // Connected but not needed
//#define PIN_EINK_SCLK 4 // EPD_SCLK
//#define PIN_EINK_MOSI 6 // EPD_MOSI
// #define USE_EINK
// #define PIN_EINK_EN -1 // N/C
// #define PIN_EINK_CS 9 // EPD_CS
// #define PIN_EINK_BUSY 18 // EPD_BUSY
// #define PIN_EINK_DC 19 // EPD_D/C
// #define PIN_EINK_RES -1 // Connected but not needed
// #define PIN_EINK_SCLK 4 // EPD_SCLK
// #define PIN_EINK_MOSI 6 // EPD_MOSI

View File

@@ -4,7 +4,7 @@
#define I2C_SCL 22
// #define BUTTON_PIN 39 // 38, 37
//#define BUTTON_PIN 0
// #define BUTTON_PIN 0
#define BUTTON_NEED_PULLUP
// #define EXT_NOTIFY_OUT 13 // Default pin to use for Ext Notify Plugin.

View File

@@ -3,8 +3,8 @@
#define I2C_SCL 22
// 7-07-2023 Or enable Secondary I2C Bus
//#define I2C_SDA1 32
//#define I2C_SCL1 33
// #define I2C_SDA1 32
// #define I2C_SCL1 33
#define HAS_GPS 1
#undef GPS_RX_PIN
@@ -39,7 +39,7 @@
#undef RF95_MOSI
#undef RF95_NSS
#define USE_RF95
//#define USE_SX1280
// #define USE_SX1280
#ifdef USE_RF95
#define RF95_SCK 18

View File

@@ -64,7 +64,7 @@ extern "C" {
* Buttons
*/
//#define PIN_BUTTON1 9 // Pin for button on E-ink button module or IO expansion
// #define PIN_BUTTON1 9 // Pin for button on E-ink button module or IO expansion
#define BUTTON_NEED_PULLUP
#define PIN_BUTTON2 12
#define PIN_BUTTON3 24
@@ -191,7 +191,9 @@ SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG
// #define SX126X_TXEN (39)
// #define SX126X_RXEN (37)
#define SX126X_POWER_EN (37)
#define SX126X_E22 // DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3
#define SX126X_DIO2_AS_RF_SWITCH // DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
#define PIN_GPS_RESET (34) // Must be P1.02
// #define PIN_GPS_EN
@@ -220,7 +222,7 @@ SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG
#define ADC_MULTIPLIER VBAT_DIVIDER_COMP // REAL_VBAT_MV_PER_LSB
#define VBAT_RAW_TO_SCALED(x) (REAL_VBAT_MV_PER_LSB * x)
//#define HAS_RTC 1
// #define HAS_RTC 1
#define HAS_ETHERNET 1
@@ -237,4 +239,4 @@ SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG
* Arduino objects - C++ only
*----------------------------------------------------------------------------*/
#endif
#endif

View File

@@ -24,11 +24,11 @@ static const uint8_t SCK = 5;
static const uint8_t MOSI = 6;
static const uint8_t SS = 7;
//#define SPI_MOSI (11)
//#define SPI_SCK (14)
//#define SPI_MISO (2)
//#define SPI_CS (13)
// #define SPI_MOSI (11)
// #define SPI_SCK (14)
// #define SPI_MISO (2)
// #define SPI_CS (13)
//#define SDCARD_CS SPI_CS
// #define SDCARD_CS SPI_CS
#endif /* Pins_Arduino_h */

View File

@@ -2,22 +2,22 @@
#undef GPS_RX_PIN
#undef GPS_TX_PIN
//#define HAS_SCREEN 0
//#define HAS_SDCARD
//#define SDCARD_USE_SPI1
// #define HAS_SCREEN 0
// #define HAS_SDCARD
// #define SDCARD_USE_SPI1
//#define USE_SSD1306
// #define USE_SSD1306
#define I2C_SDA 18 // 1 // I2C pins for this board
#define I2C_SCL 17 // 2
//#define LED_PIN 38 // This is a RGB LED not a standard LED
// #define LED_PIN 38 // This is a RGB LED not a standard LED
#define BUTTON_PIN 0 // This is the BOOT button
#define BUTTON_NEED_PULLUP
//#define USE_RF95 // RFM95/SX127x
//#define USE_SX1262
// #define USE_RF95 // RFM95/SX127x
// #define USE_SX1262
#define USE_SX1280
#define RF95_MISO 3

View File

@@ -24,11 +24,11 @@ static const uint8_t SCK = 5;
static const uint8_t MOSI = 6;
static const uint8_t SS = 7;
//#define SPI_MOSI (11)
//#define SPI_SCK (14)
//#define SPI_MISO (2)
//#define SPI_CS (13)
// #define SPI_MOSI (11)
// #define SPI_SCK (14)
// #define SPI_MISO (2)
// #define SPI_CS (13)
//#define SDCARD_CS SPI_CS
// #define SDCARD_CS SPI_CS
#endif /* Pins_Arduino_h */

View File

@@ -2,22 +2,22 @@
#undef GPS_RX_PIN
#undef GPS_TX_PIN
//#define HAS_SCREEN 0
//#define HAS_SDCARD
//#define SDCARD_USE_SPI1
// #define HAS_SCREEN 0
// #define HAS_SDCARD
// #define SDCARD_USE_SPI1
#define USE_SSD1306
#define I2C_SDA 18 // 1 // I2C pins for this board
#define I2C_SCL 17 // 2
//#define LED_PIN 38 // This is a RGB LED not a standard LED
// #define LED_PIN 38 // This is a RGB LED not a standard LED
#define BUTTON_PIN 0 // This is the BOOT button
#define BUTTON_NEED_PULLUP
//#define USE_RF95 // RFM95/SX127x
//#define USE_SX1262
// #define USE_RF95 // RFM95/SX127x
// #define USE_SX1262
#define USE_SX1280
#define RF95_MISO 3
@@ -44,13 +44,13 @@
#define SX128X_RESET LORA_RESET
#endif
//#define USE_EINK
// #define USE_EINK
/*
* eink display pins
*/
//#define PIN_EINK_CS 13
//#define PIN_EINK_BUSY 2
//#define PIN_EINK_DC 1
//#define PIN_EINK_RES (-1)
//#define PIN_EINK_SCLK 5
//#define PIN_EINK_MOSI 6
// #define PIN_EINK_CS 13
// #define PIN_EINK_BUSY 2
// #define PIN_EINK_DC 1
// #define PIN_EINK_RES (-1)
// #define PIN_EINK_SCLK 5
// #define PIN_EINK_MOSI 6

View File

@@ -4,8 +4,8 @@
#define I2C_SCL 22
#define BUTTON_PIN 36 // The user button (information button) GPIO on the Nano G1 explorer
//#define BUTTON_PIN_ALT 13 // Alternate GPIO for an external button if needed. Does anyone use this? It is not documented
// anywhere.
// #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.
// common pinout for their SX1262 vs RF95 modules - both can be enabled and we will probe at runtime for RF95 and if
@@ -13,6 +13,9 @@
#define USE_RF95
#define USE_SX1262
#define GPS_RX_PIN 34
#define GPS_TX_PIN 12
#define LORA_DIO0 26 // a No connect on the SX1262 module
#define LORA_RESET 23
#define LORA_DIO1 33 // SX1262 IRQ
@@ -24,7 +27,9 @@
#define SX126X_DIO1 LORA_DIO1
#define SX126X_BUSY LORA_DIO2
#define SX126X_RESET LORA_RESET
#define SX126X_E22 // Not really an E22
// Not really an E22
#define SX126X_DIO2_AS_RF_SWITCH
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
// Internally the module hooks the SX1262-DIO2 in to control the TX/RX switch (which is the default for the sx1262interface
// code)
#endif
@@ -34,4 +39,4 @@
#define BATTERY_SENSE_SAMPLES 15 // Set the number of samples, It has an effect of increasing sensitivity.
#define ADC_MULTIPLIER 2
#define USE_SH1107_128_64
#define USE_SH1107_128_64

View File

@@ -4,8 +4,8 @@
#define I2C_SCL 22
#define BUTTON_PIN 36 // The middle button GPIO on the Nano G1
//#define BUTTON_PIN_ALT 13 // Alternate GPIO for an external button if needed. Does anyone use this? It is not documented
// anywhere.
// #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.
// common pinout for their SX1262 vs RF95 modules - both can be enabled and we will probe at runtime for RF95 and if
@@ -13,6 +13,9 @@
#define USE_RF95
#define USE_SX1262
#define GPS_RX_PIN 34
#define GPS_TX_PIN 12
#define LORA_DIO0 26 // a No connect on the SX1262 module
#define LORA_RESET 23
#define LORA_DIO1 33 // SX1262 IRQ
@@ -24,10 +27,12 @@
#define SX126X_DIO1 LORA_DIO1
#define SX126X_BUSY LORA_DIO2
#define SX126X_RESET LORA_RESET
#define SX126X_E22 // Not really an E22
// Not really an E22
#define SX126X_DIO2_AS_RF_SWITCH
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
// Internally the module hooks the SX1262-DIO2 in to control the TX/RX switch (which is the default for the sx1262interface
// code)
#endif
// different screen
#define USE_SH1106
#define USE_SH1106

View File

@@ -23,7 +23,7 @@
#define VARIANT_MCK (64000000ul)
#define USE_LFXO // Board uses 32khz crystal for LF
//#define USE_LFRC // Board uses 32khz RC for LF
// #define USE_LFRC // Board uses 32khz RC for LF
/*----------------------------------------------------------------------------
* Headers
@@ -54,7 +54,7 @@ extern "C" {
#define LED_CONN PIN_GREEN
#define LED_STATE_ON 0 // State when LED is lit
//#define LED_INVERTED 1
// #define LED_INVERTED 1
/*
* Buttons
@@ -114,11 +114,13 @@ External serial flash W25Q16JV_IQ
#define SX126X_CS (32 + 13) // FIXME - we really should define LORA_CS instead
#define SX126X_DIO1 (32 + 10)
// Note DIO2 is attached internally to the module to an analog switch for TX/RX switching
//#define SX1262_DIO3 (0 + 21)
// #define SX1262_DIO3 (0 + 21)
// This is used as an *output* from the sx1262 and connected internally to power the tcxo, do not drive from the main CPU?
#define SX126X_BUSY (32 + 11)
#define SX126X_RESET (32 + 15)
#define SX126X_E22 // DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3
// DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3
#define SX126X_DIO2_AS_RF_SWITCH
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
// #define LORA_DISABLE_SENDING // Define this to disable transmission for testing (power testing etc...)
@@ -130,11 +132,11 @@ External serial flash W25Q16JV_IQ
#define GPS_L76K
#define PIN_GPS_WAKE (0 + 13) // An output to wake GPS, low means allow sleep, high means force wake
#define PIN_GPS_TX (0 + 9) // This is for bits going TOWARDS the CPU
#define PIN_GPS_RX (0 + 10) // This is for bits going TOWARDS the GPS
#define PIN_GPS_STANDBY (0 + 13) // An output to wake GPS, low means allow sleep, high means force wake STANDBY
#define PIN_GPS_TX (0 + 9) // This is for bits going TOWARDS the CPU
#define PIN_GPS_RX (0 + 10) // This is for bits going TOWARDS the GPS
//#define GPS_THREAD_INTERVAL 50
// #define GPS_THREAD_INTERVAL 50
#define PIN_SERIAL1_RX PIN_GPS_TX
#define PIN_SERIAL1_TX PIN_GPS_RX
@@ -152,7 +154,7 @@ External serial flash W25Q16JV_IQ
#define PIN_SPI_MOSI (0 + 11)
#define PIN_SPI_SCK (0 + 12)
//#define PIN_PWR_EN (0 + 6)
// #define PIN_PWR_EN (0 + 6)
// To debug via the segger JLINK console rather than the CDC-ACM serial device
// #define USE_SEGGER
@@ -193,4 +195,4 @@ External serial flash W25Q16JV_IQ
* Arduino objects - C++ only
*----------------------------------------------------------------------------*/
#endif
#endif

View File

@@ -146,6 +146,7 @@ static const uint8_t SCK = PIN_SPI_SCK;
#define SX126X_BUSY (32 + 4) // P1.04
#define SX126X_RESET (0 + 3) // P0.03
#define SX126X_ANT_SW (32 + 10) // P1.10
#define SX126X_DIO2_AS_RF_SWITCH
// To debug via the segger JLINK console rather than the CDC-ACM serial device
// #define USE_SEGGER

View File

@@ -1,7 +1,7 @@
[env:picomputer-s3]
extends = esp32s3_base
board = bpi_picow_esp32_s3
board_level = extra
;OpenOCD flash method
;upload_protocol = esp-builtin
;Normal method

View File

@@ -5,9 +5,14 @@
#define PIN_BUZZER 43
#define HAS_GPS 0
#define HAS_WIRE 0
#define BATTERY_PIN ADC1_CHANNEL_1_GPIO_NUM // 2
// A battery voltage measurement pin, voltage divider connected here to measure battery voltage
// ratio of voltage divider = 3.0 (R11=200k, R7=100k)
#define ADC_MULTIPLIER 3.1 // 3.0 with correction of display undervoltage.
#define ADC_CHANNEL ADC1_GPIO2_CHANNEL
#define USE_RF95 // RFM95/SX127x
#define RF95_SCK SCK // 21

View File

@@ -20,5 +20,6 @@
#define SX126X_DIO1 LORA_DIO1
#define SX126X_BUSY LORA_DIO2
#define SX126X_RESET LORA_RESET
#define SX126X_DIO2_AS_RF_SWITCH
// HOPE RFM90 does not have a TCXO therefore not SX126X_E22
#endif

View File

@@ -89,8 +89,8 @@ static const uint8_t A7 = PIN_A7;
// Other pins
#define PIN_AREF (0xff)
//#define PIN_NFC1 (9)
//#define PIN_NFC2 (10)
// #define PIN_NFC1 (9)
// #define PIN_NFC2 (10)
static const uint8_t AREF = PIN_AREF;
@@ -103,8 +103,8 @@ static const uint8_t AREF = PIN_AREF;
#define PIN_SERIAL1_TX (9)
// Connected to Jlink CDC
//#define PIN_SERIAL2_RX (8)
//#define PIN_SERIAL2_TX (6)
// #define PIN_SERIAL2_RX (8)
// #define PIN_SERIAL2_TX (6)
/*
* SPI Interfaces
@@ -138,7 +138,8 @@ static const uint8_t SCK = PIN_SPI_SCK;
// #define SX126X_ANT_SW (32 + 10)
#define SX126X_RXEN (22)
#define SX126X_TXEN (24)
#define SX126X_E22 // Indicates this SX1262 is inside of an ebyte E22 module and special config should be done for that
// Indicates this SX1262 is inside of an ebyte E22 module and special config should be done for that
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
// ERC12864-10 LCD
#define ERC12864_CS (32 + 4)

View File

@@ -89,8 +89,8 @@ static const uint8_t A7 = PIN_A7;
// Other pins
#define PIN_AREF (0xff)
//#define PIN_NFC1 (9)
//#define PIN_NFC2 (10)
// #define PIN_NFC1 (9)
// #define PIN_NFC2 (10)
static const uint8_t AREF = PIN_AREF;
@@ -158,7 +158,8 @@ static const uint8_t SCK = PIN_SPI_SCK;
#define SX126X_RESET (0 + 17)
#define SX126X_TXEN (0 + 24)
#define SX126X_RXEN (0 + 22)
#define SX126X_E22 // Not really an E22 but this board clones using DIO3 for tcxo control
// Not really an E22 but this board clones using DIO3 for tcxo control
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
// FIXME, to prevent burning out parts I've set the power level super low, because I don't have
// an antenna wired up

View File

@@ -81,4 +81,6 @@ static const uint8_t SCK = 33;
#define SX126X_BUSY LORA_DIO2
#define SX126X_RESET LORA_RESET
#define SX126X_POWER_EN WB_IO3
#define SX126X_E22 // DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3
// DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3
#define SX126X_DIO2_AS_RF_SWITCH
#define SX126X_DIO3_TCXO_VOLTAGE 1.8

View File

@@ -11,8 +11,6 @@
#undef ECB
#define ECB 0
#undef GPS_SERIAL_NUM
#define LED_CONN PIN_LED2
#define LED_PIN LED_BUILTIN
@@ -50,5 +48,7 @@
#define SX126X_BUSY LORA_DIO2
#define SX126X_RESET LORA_RESET
#define SX126X_POWER_EN 25
#define SX126X_E22 // DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3
#endif
// DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3
#define SX126X_DIO2_AS_RF_SWITCH
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
#endif

View File

@@ -209,7 +209,9 @@ SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG
// #define SX126X_TXEN (39)
// #define SX126X_RXEN (37)
#define SX126X_POWER_EN (37)
#define SX126X_E22 // DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3
// DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3
#define SX126X_DIO2_AS_RF_SWITCH
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
// enables 3.3V periphery like GPS or IO Module
#define PIN_3V3_EN (34)
@@ -228,7 +230,6 @@ SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG
#define GPS_TX_PIN PIN_SERIAL1_TX
// Define pin to enable GPS toggle (set GPIO to LOW) via user button triple press
#define PIN_GPS_EN 34 // GPS power enable pin
// RAK12002 RTC Module
#define RV3028_RTC (uint8_t)0b1010010

View File

@@ -186,7 +186,9 @@ static const uint8_t SCK = PIN_SPI_SCK;
// #define SX126X_TXEN (39)
// #define SX126X_RXEN (37)
#define SX126X_POWER_EN (37)
#define SX126X_E22 // DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3
// DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3
#define SX126X_DIO2_AS_RF_SWITCH
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
// enables 3.3V periphery like GPS or IO Module
#define PIN_3V3_EN (34)
@@ -239,4 +241,4 @@ static const uint8_t SCK = PIN_SPI_SCK;
* Arduino objects - C++ only
*----------------------------------------------------------------------------*/
#endif
#endif

View File

@@ -43,7 +43,7 @@ extern "C" {
#define PIN_BUTTON1 9 // Pin for button on E-ink button module or IO expansion
#define BUTTON_NEED_PULLUP
//#define PIN_BUTTON2 12
// #define PIN_BUTTON2 12
/*
* Analog pins
@@ -69,8 +69,8 @@ static const uint8_t A7 = PIN_A7;
// Other pins
#define PIN_AREF (2)
//#define PIN_NFC1 (9)
//#define PIN_NFC2 (10)
// #define PIN_NFC1 (9)
// #define PIN_NFC2 (10)
static const uint8_t AREF = PIN_AREF;
@@ -111,7 +111,7 @@ static const uint8_t SCK = PIN_SPI_SCK;
#define PIN_EINK_CS (0 + 16) // TX1
#define PIN_EINK_BUSY (0 + 15) // RX1
#define PIN_EINK_DC (0 + 17) // IO1
//#define PIN_EINK_RES (-1) //first try without RESET then connect it to AIN (AIN0 5 )
// #define PIN_EINK_RES (-1) //first try without RESET then connect it to AIN (AIN0 5 )
#define PIN_EINK_RES (0 + 5) // 2.13 BN Display needs RESET
#define PIN_EINK_SCLK (0 + 14) // SCL
#define PIN_EINK_MOSI (0 + 13) // SDA
@@ -155,7 +155,9 @@ static const uint8_t SCK = PIN_SPI_SCK;
// #define SX126X_TXEN (39)
// #define SX126X_RXEN (37)
#define SX126X_POWER_EN (37)
#define SX126X_E22 // DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3
// DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3
#define SX126X_DIO2_AS_RF_SWITCH
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
// enables 3.3V periphery like GPS or IO Module
#define PIN_3V3_EN (34)
@@ -171,36 +173,36 @@ static const uint8_t SCK = PIN_SPI_SCK;
// Therefore must be 1 to keep peripherals powered
// Power is on the controllable 3V3_S rail
// #define PIN_GPS_RESET (34)
//#define PIN_GPS_EN PIN_3V3_EN
//#define PIN_GPS_PPS (17) // Pulse per second input from the GPS
// #define PIN_GPS_EN PIN_3V3_EN
// #define PIN_GPS_PPS (17) // Pulse per second input from the GPS
//#define GPS_RX_PIN PIN_SERIAL1_RX
//#define GPS_TX_PIN PIN_SERIAL1_TX
// #define GPS_RX_PIN PIN_SERIAL1_RX
// #define GPS_TX_PIN PIN_SERIAL1_TX
// RAK12002 RTC Module
#define RV3028_RTC (uint8_t)0b1010010
// Battery
// The battery sense is hooked to pin A0 (5)
//#define BATTERY_PIN PIN_A0
// #define BATTERY_PIN PIN_A0
// and has 12 bit resolution
//#define BATTERY_SENSE_RESOLUTION_BITS 12
//#define BATTERY_SENSE_RESOLUTION 4096.0
// #define BATTERY_SENSE_RESOLUTION_BITS 12
// #define BATTERY_SENSE_RESOLUTION 4096.0
// Definition of milliVolt per LSB => 3.0V ADC range and 12-bit ADC resolution = 3000mV/4096
//#define VBAT_MV_PER_LSB (0.73242188F)
// #define VBAT_MV_PER_LSB (0.73242188F)
// Voltage divider value => 1.5M + 1M voltage divider on VBAT = (1.5M / (1M + 1.5M))
//#define VBAT_DIVIDER (0.4F)
// #define VBAT_DIVIDER (0.4F)
// Compensation factor for the VBAT divider
//#define VBAT_DIVIDER_COMP (1.73)
// #define VBAT_DIVIDER_COMP (1.73)
// Fixed calculation of milliVolt from compensation value
//#define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB)
//#undef AREF_VOLTAGE
//#define AREF_VOLTAGE 3.0
//#define VBAT_AR_INTERNAL AR_INTERNAL_3_0
//#define ADC_MULTIPLIER VBAT_DIVIDER_COMP // REAL_VBAT_MV_PER_LSB
//#define VBAT_RAW_TO_SCALED(x) (REAL_VBAT_MV_PER_LSB * x)
// #define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB)
// #undef AREF_VOLTAGE
// #define AREF_VOLTAGE 3.0
// #define VBAT_AR_INTERNAL AR_INTERNAL_3_0
// #define ADC_MULTIPLIER VBAT_DIVIDER_COMP // REAL_VBAT_MV_PER_LSB
// #define VBAT_RAW_TO_SCALED(x) (REAL_VBAT_MV_PER_LSB * x)
//#define HAS_RTC 1
// #define HAS_RTC 1
#ifdef __cplusplus
}
@@ -210,4 +212,4 @@ static const uint8_t SCK = PIN_SPI_SCK;
* Arduino objects - C++ only
*----------------------------------------------------------------------------*/
#endif
#endif

View File

@@ -11,14 +11,16 @@
#undef ECB
#define ECB 0
#define NO_GPS 1
#define USE_SH1106 1
#undef GPS_SERIAL_NUM
// default I2C pins:
// SDA = 4
// SCL = 5
// Recommended pins for SerialModule:
// txd = 8
// rxd = 9
#define EXT_NOTIFY_OUT 22
#define BUTTON_PIN 17
@@ -51,5 +53,6 @@
#define SX126X_DIO1 LORA_DIO1
#define SX126X_BUSY LORA_DIO2
#define SX126X_RESET LORA_RESET
#define SX126X_E22
#endif
#define SX126X_DIO2_AS_RF_SWITCH
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
#endif

View File

@@ -11,14 +11,16 @@
#undef ECB
#define ECB 0
#define NO_GPS 1
#define USE_SH1106 1
#undef GPS_SERIAL_NUM
// default I2C pins:
// SDA = 4
// SCL = 5
// Recommended pins for SerialModule:
// txd = 8
// rxd = 9
#define EXT_NOTIFY_OUT 22
#define BUTTON_PIN 17
@@ -49,5 +51,6 @@
#define SX126X_DIO1 LORA_DIO1
#define SX126X_BUSY LORA_DIO2
#define SX126X_RESET LORA_RESET
#define SX126X_E22
#endif
#define SX126X_DIO2_AS_RF_SWITCH
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
#endif

View File

@@ -3,9 +3,12 @@
#define I2C_SDA 21
#define I2C_SCL 22
#define I2C_SDA1 14 // Second i2c channel on external IO connector
#define I2C_SCL1 15 // Second i2c channel on external IO connector
#define BUTTON_PIN 36 // The middle button GPIO on the Nano G1
//#define BUTTON_PIN_ALT 13 // Alternate GPIO for an external button if needed. Does anyone use this? It is not documented
// anywhere.
// #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.
// common pinout for their SX1262 vs RF95 modules - both can be enabled and we will probe at runtime for RF95 and if
@@ -24,9 +27,7 @@
#define SX126X_DIO1 LORA_DIO1
#define SX126X_BUSY LORA_DIO2
#define SX126X_RESET LORA_RESET
//#define SX126X_E22 // Not really an E22
// Internally the module hooks the SX1262-DIO2 in to control the TX/RX switch (which is the default for the sx1262interface
// code)
#define SX126X_DIO2_AS_RF_SWITCH // Internally the module hooks the SX1262-DIO2 in to control the TX/RX switch
#define SX126X_MAX_POWER \
16 // Ensure the PA does not exceed the saturation output power. More
// Info:https://uniteng.com/wiki/doku.php?id=meshtastic:station#rf_design_-_lora_station_edition_g1
@@ -42,4 +43,8 @@
#define BAT_NOBATVOLT 6690
// different screen
#define USE_SH1106
#define USE_SH1106
// Station may not have GPS installed, but it has a labeled GPS pinout
#define GPS_RX_PIN 34
#define GPS_TX_PIN 12

View File

@@ -8,7 +8,8 @@ debug_tool = esp-builtin
build_flags = ${esp32_base.build_flags}
-DT_DECK
-DBOARD_HAS_PSRAM
-DGPS_POWER_TOGGLE
-Ivariants/t-deck
lib_deps = ${esp32s3_base.lib_deps}
lovyan03/LovyanGFX@^1.1.8
lovyan03/LovyanGFX@^1.1.9

View File

@@ -27,8 +27,8 @@
#define BUTTON_PIN 0
// #define BUTTON_NEED_PULLUP
#undef GPS_RX_PIN
#undef GPS_TX_PIN
#define GPS_RX_PIN 44
#define GPS_TX_PIN 43
// Have SPI interface SD card slot
#define HAS_SDCARD 1
@@ -41,7 +41,7 @@
#define BATTERY_PIN 4 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
// ratio of voltage divider = 2.0 (RD2=100k, RD3=100k)
#define ADC_MULTIPLIER 2.11 // 2.0 + 10% for correction of display undervoltage.
#define ADC_CHANNEL ADC1_GPIO1_CHANNEL
#define ADC_CHANNEL ADC1_GPIO4_CHANNEL
// keyboard
#define I2C_SDA 18 // I2C pins for this board
@@ -84,6 +84,8 @@
#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
// Not really an E22 but TTGO seems to be trying to clone that
#define SX126X_DIO2_AS_RF_SWITCH
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
// Internally the TTGO module hooks the SX1262-DIO2 in to control the TX/RX switch (which is the default for the sx1262interface
// code)
// code)

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