mirror of
https://github.com/meshtastic/firmware.git
synced 2026-01-09 03:17:31 +00:00
Compare commits
44 Commits
v2.2.7.e89
...
v2.2.11.10
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
10265aabd5 | ||
|
|
8780d93941 | ||
|
|
54f0c045e4 | ||
|
|
3ddad671a5 | ||
|
|
dc6f0b8e0b | ||
|
|
33f28c3d56 | ||
|
|
ef1d8c8eee | ||
|
|
950d5f0946 | ||
|
|
fc06754e1f | ||
|
|
fbf74fc0b2 | ||
|
|
7cebd79475 | ||
|
|
aa38f53aed | ||
|
|
2a6c8be684 | ||
|
|
37c3d15978 | ||
|
|
f301e236eb | ||
|
|
94c2ade272 | ||
|
|
a6e4402e41 | ||
|
|
50db2d0e9b | ||
|
|
5ecdbd0dbb | ||
|
|
47c6738c0d | ||
|
|
1552aa0081 | ||
|
|
6ebec8fcd9 | ||
|
|
e9215a5d70 | ||
|
|
4e3576ae48 | ||
|
|
98290e5d7b | ||
|
|
ad529924f1 | ||
|
|
07d51a2ca4 | ||
|
|
47301a5ac0 | ||
|
|
0d023ea215 | ||
|
|
b5e952db24 | ||
|
|
a1c433748a | ||
|
|
04b2ab82dc | ||
|
|
e96ba7cbcf | ||
|
|
61f6fb22c5 | ||
|
|
db7b77c76e | ||
|
|
350090ec0d | ||
|
|
cdac643749 | ||
|
|
1a2c7f00e1 | ||
|
|
7eff5e7bcb | ||
|
|
17207681ef | ||
|
|
94f7c7e472 | ||
|
|
0a12d67d19 | ||
|
|
3175a3d630 | ||
|
|
4e9bf75340 |
2
.github/pull_request_template.md
vendored
2
.github/pull_request_template.md
vendored
@@ -7,7 +7,7 @@
|
||||
is appreciated." This will allow other devs to potentially save you time by not accidentially duplicating work etc...
|
||||
- Please do not check in files that don't have real changes
|
||||
- Please do not reformat lines that you didn't have to change the code on
|
||||
- We recommend using the [Visual Studio Code](https://platformio.org/install/ide?install=vscode) editor along with the ['Trunk Check' extension](https://marketplace.visualstudio.com/items?itemName=trunk.io) (WSL2 is required on windows),
|
||||
- We recommend using the [Visual Studio Code](https://platformio.org/install/ide?install=vscode) editor along with the ['Trunk Check' extension](https://marketplace.visualstudio.com/items?itemName=trunk.io) (In beta for windows, WSL2 for the linux version),
|
||||
because it automatically follows our indentation rules and its auto reformatting will not cause spurious changes to lines.
|
||||
- If your PR fixes a bug, mention "fixes #bugnum" somewhere in your pull request description.
|
||||
- If your other co-developers have comments on your PR please tweak as needed.
|
||||
|
||||
2
.trunk/.gitignore
vendored
2
.trunk/.gitignore
vendored
@@ -2,7 +2,7 @@
|
||||
*logs
|
||||
*actions
|
||||
*notifications
|
||||
*tools
|
||||
plugins
|
||||
user_trunk.yaml
|
||||
user.yaml
|
||||
tools
|
||||
|
||||
@@ -1,53 +1,53 @@
|
||||
version: 0.1
|
||||
cli:
|
||||
version: 1.13.0
|
||||
version: 1.16.2
|
||||
plugins:
|
||||
sources:
|
||||
- id: trunk
|
||||
ref: v1.1.1
|
||||
ref: v1.2.5
|
||||
uri: https://github.com/trunk-io/plugins
|
||||
lint:
|
||||
enabled:
|
||||
- bandit@1.7.5
|
||||
- checkov@2.4.1
|
||||
- checkov@2.5.0
|
||||
- terrascan@1.18.3
|
||||
- trivy@0.44.1
|
||||
- trufflehog@3.48.0
|
||||
- trivy@0.45.1
|
||||
- trufflehog@3.59.0
|
||||
- taplo@0.8.1
|
||||
- ruff@0.0.284
|
||||
- ruff@0.0.292
|
||||
- yamllint@1.32.0
|
||||
- isort@5.12.0
|
||||
- markdownlint@0.35.0
|
||||
- markdownlint@0.37.0
|
||||
- oxipng@8.0.0
|
||||
- svgo@3.0.2
|
||||
- actionlint@1.6.25
|
||||
- actionlint@1.6.26
|
||||
- flake8@6.1.0
|
||||
- hadolint@2.12.0
|
||||
- shfmt@3.6.0
|
||||
- shellcheck@0.9.0
|
||||
- black@23.7.0
|
||||
- black@23.9.1
|
||||
- git-diff-check
|
||||
- gitleaks@8.17.0
|
||||
- gitleaks@8.18.0
|
||||
- clang-format@16.0.3
|
||||
- prettier@3.0.2
|
||||
- prettier@3.0.3
|
||||
disabled:
|
||||
- taplo@0.8.1
|
||||
- shellcheck@0.9.0
|
||||
- shfmt@3.6.0
|
||||
- oxipng@8.0.0
|
||||
- actionlint@1.6.22
|
||||
- markdownlint@0.35.0
|
||||
- markdownlint@0.37.0
|
||||
- hadolint@2.12.0
|
||||
- svgo@3.0.2
|
||||
runtimes:
|
||||
enabled:
|
||||
- python@3.10.8
|
||||
- go@1.19.5
|
||||
- go@1.21.0
|
||||
- node@18.12.1
|
||||
actions:
|
||||
disabled:
|
||||
- trunk-announce
|
||||
- trunk-check-pre-push
|
||||
- trunk-fmt-pre-commit
|
||||
enabled:
|
||||
- trunk-fmt-pre-commit
|
||||
- trunk-check-pre-push
|
||||
- trunk-upgrade-available
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
|
||||
This repository contains the device firmware for the Meshtastic project.
|
||||
|
||||
**[Building Instructions](https://meshtastic.org/docs/development/firmware/build)**
|
||||
**[Flashing Instructions](https://meshtastic.org/docs/getting-started/flashing-firmware/)**
|
||||
- **[Building Instructions](https://meshtastic.org/docs/development/firmware/build)**
|
||||
- **[Flashing Instructions](https://meshtastic.org/docs/getting-started/flashing-firmware/)**
|
||||
|
||||
## Stats
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Submodule protobufs updated: ce55381ecf...175a5c97fb
@@ -164,17 +164,17 @@ class ButtonThread : public concurrency::OSThread
|
||||
|
||||
static void userButtonMultiPressed()
|
||||
{
|
||||
#if defined(GPS_POWER_TOGGLE)
|
||||
if (gps != nullptr) {
|
||||
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);
|
||||
gps->doGPSpowersave(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();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void userButtonPressedLongStart()
|
||||
|
||||
@@ -175,9 +175,21 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
||||
uint32_t raw = 0;
|
||||
#ifdef ARCH_ESP32
|
||||
#ifndef BAT_MEASURE_ADC_UNIT // ADC1
|
||||
#ifdef ADC_CTRL
|
||||
if (heltec_version == 5) {
|
||||
pinMode(ADC_CTRL, OUTPUT);
|
||||
digitalWrite(ADC_CTRL, HIGH);
|
||||
delay(10);
|
||||
}
|
||||
#endif
|
||||
for (int i = 0; i < BATTERY_SENSE_SAMPLES; i++) {
|
||||
raw += adc1_get_raw(adc_channel);
|
||||
}
|
||||
#ifdef ADC_CTRL
|
||||
if (heltec_version == 5) {
|
||||
digitalWrite(ADC_CTRL, LOW);
|
||||
}
|
||||
#endif
|
||||
#else // ADC2
|
||||
int32_t adc_buf = 0;
|
||||
for (int i = 0; i < BATTERY_SENSE_SAMPLES; i++) {
|
||||
@@ -414,7 +426,7 @@ void Power::shutdown()
|
||||
#ifdef PIN_LED3
|
||||
ledOff(PIN_LED2);
|
||||
#endif
|
||||
doDeepSleep(DELAY_FOREVER);
|
||||
doDeepSleep(DELAY_FOREVER, false);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
@@ -158,9 +154,6 @@ static void darkEnter()
|
||||
{
|
||||
setBluetoothEnable(true);
|
||||
screen->setOn(false);
|
||||
#ifdef KB_POWERON
|
||||
digitalWrite(KB_POWERON, LOW);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void serialEnter()
|
||||
@@ -188,9 +181,6 @@ static void powerEnter()
|
||||
} else {
|
||||
screen->setOn(true);
|
||||
setBluetoothEnable(true);
|
||||
#ifdef KB_POWERON
|
||||
digitalWrite(KB_POWERON, HIGH);
|
||||
#endif
|
||||
// within enter() the function getState() returns the state we came from
|
||||
if (strcmp(powerFSM.getState()->name, "BOOT") != 0 && strcmp(powerFSM.getState()->name, "POWER") != 0 &&
|
||||
strcmp(powerFSM.getState()->name, "DARK") != 0) {
|
||||
@@ -221,9 +211,6 @@ static void onEnter()
|
||||
LOG_DEBUG("Enter state: ON\n");
|
||||
screen->setOn(true);
|
||||
setBluetoothEnable(true);
|
||||
#ifdef KB_POWERON
|
||||
digitalWrite(KB_POWERON, HIGH);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void onIdle()
|
||||
@@ -258,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);
|
||||
@@ -361,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");
|
||||
@@ -374,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
|
||||
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
415
src/gps/GPS.cpp
415
src/gps/GPS.cpp
@@ -2,6 +2,7 @@
|
||||
#include "NodeDB.h"
|
||||
#include "RTC.h"
|
||||
#include "configuration.h"
|
||||
#include "main.h" // pmu_found
|
||||
#include "sleep.h"
|
||||
#include "ubx.h"
|
||||
|
||||
@@ -19,7 +20,7 @@ HardwareSerial *GPS::_serial_gps = &Serial1;
|
||||
HardwareSerial *GPS::_serial_gps = NULL;
|
||||
#endif
|
||||
|
||||
GPS *gps;
|
||||
GPS *gps = nullptr;
|
||||
|
||||
/// Multiple GPS instances might use the same serial port (in sequence), but we can
|
||||
/// only init that port once.
|
||||
@@ -75,28 +76,25 @@ GPS_RESPONSE GPS::getACK(const char *message, uint32_t waitMillis)
|
||||
while (millis() < startTimeout) {
|
||||
if (_serial_gps->available()) {
|
||||
b = _serial_gps->read();
|
||||
#ifdef GPS_DEBUG
|
||||
LOG_DEBUG("%02X", (char *)buffer);
|
||||
#endif
|
||||
buffer[bytesRead] = b;
|
||||
bytesRead++;
|
||||
if ((bytesRead == 767) || (b == '\r')) {
|
||||
if (strnstr((char *)buffer, message, bytesRead) != nullptr) {
|
||||
#ifdef GPS_DEBUG
|
||||
buffer[bytesRead] = '\0';
|
||||
LOG_DEBUG("%s\r", (char *)buffer);
|
||||
LOG_DEBUG("\r");
|
||||
#endif
|
||||
return GNSS_RESPONSE_OK;
|
||||
} else {
|
||||
#ifdef GPS_DEBUG
|
||||
buffer[bytesRead] = '\0';
|
||||
LOG_INFO("Bytes read:%s\n", (char *)buffer);
|
||||
#endif
|
||||
bytesRead = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef GPS_DEBUG
|
||||
buffer[bytesRead] = '\0';
|
||||
LOG_INFO("Bytes read:%s\n", (char *)buffer);
|
||||
LOG_DEBUG("\n");
|
||||
#endif
|
||||
return GNSS_RESPONSE_NONE;
|
||||
}
|
||||
@@ -251,10 +249,18 @@ int GPS::getACK(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t
|
||||
bool GPS::setup()
|
||||
{
|
||||
int msglen = 0;
|
||||
bool isProblematicGPS = false;
|
||||
|
||||
if (_serial_gps && !didSerialInit) {
|
||||
if (!didSerialInit) {
|
||||
#if !defined(GPS_UC6580)
|
||||
if (tx_gpio) {
|
||||
#ifdef HAS_PMU
|
||||
// The T-Beam 1.2 has issues with the GPS
|
||||
if (HW_VENDOR == meshtastic_HardwareModel_TBEAM && PMU->getChipModel() == XPOWERS_AXP2101) {
|
||||
gnssModel = GNSS_MODEL_UBLOX;
|
||||
isProblematicGPS = true;
|
||||
}
|
||||
#endif
|
||||
if (tx_gpio && gnssModel == GNSS_MODEL_UNKNOWN) {
|
||||
LOG_DEBUG("Probing for GPS at %d \n", serialSpeeds[speedSelect]);
|
||||
gnssModel = probe(serialSpeeds[speedSelect]);
|
||||
if (gnssModel == GNSS_MODEL_UNKNOWN) {
|
||||
@@ -389,74 +395,116 @@ bool GPS::setup()
|
||||
LOG_WARN("Unable to enable powersaving for GPS.\n");
|
||||
}
|
||||
} else {
|
||||
if (strncmp(info.hwVersion, "00040007", 8) == 0) { // This PSM mode has only been tested on this hardware
|
||||
msglen = makeUBXPacket(0x06, 0x11, 0x2, _message_CFG_RXM_PSM);
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x11, 300) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to enable powersaving mode for GPS.\n");
|
||||
}
|
||||
msglen = makeUBXPacket(0x06, 0x3B, 44, _message_CFG_PM2);
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x3B, 300) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to enable powersaving details for GPS.\n");
|
||||
}
|
||||
} else {
|
||||
msglen = makeUBXPacket(0x06, 0x11, 0x2, _message_CFG_RXM_ECO);
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x11, 300) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to enable powersaving ECO mode for GPS.\n");
|
||||
if (!(isProblematicGPS)) {
|
||||
if (strncmp(info.hwVersion, "00040007", 8) == 0) { // This PSM mode has only been tested on this hardware
|
||||
msglen = makeUBXPacket(0x06, 0x11, 0x2, _message_CFG_RXM_PSM);
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x11, 300) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to enable powersaving mode for GPS.\n");
|
||||
}
|
||||
msglen = makeUBXPacket(0x06, 0x3B, 44, _message_CFG_PM2);
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x3B, 300) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to enable powersaving details for GPS.\n");
|
||||
}
|
||||
} else {
|
||||
msglen = makeUBXPacket(0x06, 0x11, 0x2, _message_CFG_RXM_ECO);
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x11, 300) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to enable powersaving ECO mode for GPS.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
msglen = makeUBXPacket(0x06, 0x09, sizeof(_message_SAVE), _message_SAVE);
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x09, 300) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to save GNSS module configuration.\n");
|
||||
} else {
|
||||
LOG_INFO("GNSS module configuration saved!\n");
|
||||
// The T-beam 1.2 has issues.
|
||||
if (!(isProblematicGPS)) {
|
||||
msglen = makeUBXPacket(0x06, 0x09, sizeof(_message_SAVE), _message_SAVE);
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x09, 300) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to save GNSS module configuration.\n");
|
||||
} else {
|
||||
LOG_INFO("GNSS module configuration saved!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
didSerialInit = true;
|
||||
}
|
||||
|
||||
notifySleepObserver.observe(¬ifySleep);
|
||||
notifyDeepSleepObserver.observe(¬ifyDeepSleep);
|
||||
notifyGPSSleepObserver.observe(¬ifyGPSSleep);
|
||||
|
||||
if (config.position.gps_enabled == false && config.position.fixed_position == false) {
|
||||
setAwake(false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
GPS::~GPS()
|
||||
{
|
||||
// we really should unregister our sleep observer
|
||||
notifySleepObserver.unobserve(¬ifySleep);
|
||||
notifyDeepSleepObserver.unobserve(¬ifyDeepSleep);
|
||||
notifyGPSSleepObserver.observe(¬ifyGPSSleep);
|
||||
}
|
||||
|
||||
// Allow defining the polarity of the WAKE output. default is active high
|
||||
#ifndef GPS_WAKE_ACTIVE
|
||||
#define GPS_WAKE_ACTIVE 1
|
||||
#endif
|
||||
|
||||
void GPS::wake()
|
||||
void GPS::setGPSPower(bool on, bool standbyOnly, uint32_t sleepTime)
|
||||
{
|
||||
#ifdef PIN_GPS_WAKE
|
||||
digitalWrite(PIN_GPS_WAKE, GPS_WAKE_ACTIVE);
|
||||
pinMode(PIN_GPS_WAKE, OUTPUT);
|
||||
LOG_INFO("Setting GPS power=%d\n", on);
|
||||
if (on) {
|
||||
clearBuffer(); // drop any old data waiting in the buffer before re-enabling
|
||||
if (en_gpio)
|
||||
digitalWrite(en_gpio, on ? GPS_EN_ACTIVE : !GPS_EN_ACTIVE); // turn this on if defined, every time
|
||||
}
|
||||
isInPowersave = !on;
|
||||
if (!standbyOnly && en_gpio != 0 &&
|
||||
!(HW_VENDOR == meshtastic_HardwareModel_RAK4631 && (rotaryEncoderInterruptImpl1 || upDownInterruptImpl1))) {
|
||||
LOG_DEBUG("GPS powerdown using GPS_EN_ACTIVE\n");
|
||||
digitalWrite(en_gpio, on ? GPS_EN_ACTIVE : !GPS_EN_ACTIVE);
|
||||
return;
|
||||
}
|
||||
#ifdef HAS_PMU // We only have PMUs on the T-Beam, and that board has a tiny battery to save GPS ephemera, so treat as a standby.
|
||||
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);
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void GPS::sleep()
|
||||
{
|
||||
#ifdef PIN_GPS_WAKE
|
||||
digitalWrite(PIN_GPS_WAKE, GPS_WAKE_ACTIVE ? 0 : 1);
|
||||
pinMode(PIN_GPS_WAKE, OUTPUT);
|
||||
#ifdef PIN_GPS_STANDBY // Specifically the standby pin for L76K and clones
|
||||
if (on) {
|
||||
LOG_INFO("Waking GPS");
|
||||
digitalWrite(PIN_GPS_STANDBY, 1);
|
||||
pinMode(PIN_GPS_STANDBY, OUTPUT);
|
||||
return;
|
||||
} else {
|
||||
LOG_INFO("GPS entering sleep");
|
||||
// notifyGPSSleep.notifyObservers(NULL);
|
||||
digitalWrite(PIN_GPS_STANDBY, 0);
|
||||
pinMode(PIN_GPS_STANDBY, OUTPUT);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (!on) {
|
||||
if (gnssModel == GNSS_MODEL_UBLOX) {
|
||||
uint8_t msglen;
|
||||
LOG_DEBUG("Sleep Time: %i\n", sleepTime);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
gps->_message_PMREQ[0 + i] = sleepTime >> (i * 8); // Encode the sleep time in millis into the packet
|
||||
}
|
||||
msglen = gps->makeUBXPacket(0x02, 0x41, 0x08, gps->_message_PMREQ);
|
||||
gps->_serial_gps->write(gps->UBXscratch, msglen);
|
||||
}
|
||||
} else {
|
||||
if (gnssModel == GNSS_MODEL_UBLOX) {
|
||||
gps->_serial_gps->write(0xFF);
|
||||
clearBuffer(); // This often returns old data, so drop it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Record that we have a GPS
|
||||
@@ -468,14 +516,6 @@ void GPS::setConnected()
|
||||
}
|
||||
}
|
||||
|
||||
void GPS::setNumSatellites(uint8_t n)
|
||||
{
|
||||
if (n != numSatellites) {
|
||||
numSatellites = n;
|
||||
shouldPublish = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Switch the GPS into a mode where we are actively looking for a lock, or alternatively switch GPS into a low power mode
|
||||
*
|
||||
@@ -483,23 +523,38 @@ void GPS::setNumSatellites(uint8_t n)
|
||||
*/
|
||||
void GPS::setAwake(bool on)
|
||||
{
|
||||
if (!wakeAllowed && on) {
|
||||
LOG_WARN("Inhibiting because !wakeAllowed\n");
|
||||
on = false;
|
||||
}
|
||||
|
||||
if (isAwake != on) {
|
||||
LOG_DEBUG("WANT GPS=%d\n", on);
|
||||
if (on) {
|
||||
clearBuffer(); // drop any old data waiting in the buffer
|
||||
lastWakeStartMsec = millis();
|
||||
wake();
|
||||
} else {
|
||||
lastSleepStartMsec = millis();
|
||||
sleep();
|
||||
isAwake = on;
|
||||
if (!enabled) { // short circuit if the user has disabled GPS
|
||||
setGPSPower(false, false, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
isAwake = on;
|
||||
if (on) {
|
||||
lastWakeStartMsec = millis();
|
||||
} else {
|
||||
lastSleepStartMsec = millis();
|
||||
if (GPSCycles == 1) { // Skipping initial lock time, as it will likely be much longer than average
|
||||
averageLockTime = lastSleepStartMsec - lastWakeStartMsec;
|
||||
} else if (GPSCycles > 1) {
|
||||
averageLockTime += ((int32_t)(lastSleepStartMsec - lastWakeStartMsec) - averageLockTime) / (int32_t)GPSCycles;
|
||||
}
|
||||
GPSCycles++;
|
||||
LOG_DEBUG("GPS Lock took %d, average %d\n", (lastSleepStartMsec - lastWakeStartMsec) / 1000, averageLockTime / 1000);
|
||||
}
|
||||
if ((int32_t)getSleepTime() - averageLockTime >
|
||||
15 * 60 * 1000) { // 15 minutes is probably long enough to make a complete poweroff worth it.
|
||||
setGPSPower(on, false, getSleepTime() - averageLockTime);
|
||||
} else if ((int32_t)getSleepTime() - averageLockTime > 10000) { // 10 seconds is enough for standby
|
||||
#ifdef GPS_UC6580
|
||||
setGPSPower(on, false, getSleepTime() - averageLockTime);
|
||||
#else
|
||||
setGPSPower(on, true, getSleepTime() - averageLockTime);
|
||||
#endif
|
||||
} else if (averageLockTime > 20000) {
|
||||
averageLockTime -= 1000; // eventually want to sleep again.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -519,10 +574,9 @@ uint32_t GPS::getWakeTime() const
|
||||
uint32_t GPS::getSleepTime() const
|
||||
{
|
||||
uint32_t t = config.position.gps_update_interval;
|
||||
bool gps_enabled = config.position.gps_enabled;
|
||||
|
||||
// We'll not need the GPS thread to wake up again after first acq. with fixed position.
|
||||
if (!gps_enabled || config.position.fixed_position)
|
||||
if (!config.position.gps_enabled || config.position.fixed_position)
|
||||
t = UINT32_MAX; // Sleep forever now
|
||||
|
||||
if (t == UINT32_MAX)
|
||||
@@ -537,22 +591,29 @@ void GPS::publishUpdate()
|
||||
shouldPublish = false;
|
||||
|
||||
// In debug logs, identify position by @timestamp:stage (stage 2 = publish)
|
||||
LOG_DEBUG("publishing pos@%x:2, hasVal=%d, GPSlock=%d\n", p.timestamp, hasValidLocation, hasLock());
|
||||
LOG_DEBUG("publishing pos@%x:2, hasVal=%d, Sats=%d, GPSlock=%d\n", p.timestamp, hasValidLocation, p.sats_in_view,
|
||||
hasLock());
|
||||
|
||||
// Notify any status instances that are observing us
|
||||
const meshtastic::GPSStatus status = meshtastic::GPSStatus(hasValidLocation, isConnected(), isPowerSaving(), p);
|
||||
newStatus.notifyObservers(&status);
|
||||
if (config.position.gps_enabled)
|
||||
positionModule->handleNewPosition();
|
||||
}
|
||||
}
|
||||
|
||||
int32_t GPS::runOnce()
|
||||
{
|
||||
if (!GPSInitFinished) {
|
||||
if (!_serial_gps)
|
||||
return disable();
|
||||
if (!setup())
|
||||
return 2000; // Setup failed, re-run in two seconds
|
||||
|
||||
// We have now loaded our saved preferences from flash
|
||||
|
||||
if (config.position.gps_enabled == false) {
|
||||
return disable();
|
||||
}
|
||||
// ONCE we will factory reset the GPS for bug #327
|
||||
if (!devicestate.did_gps_reset) {
|
||||
LOG_WARN("GPS FactoryReset requested\n");
|
||||
@@ -562,17 +623,12 @@ int32_t GPS::runOnce()
|
||||
}
|
||||
}
|
||||
GPSInitFinished = true;
|
||||
if (config.position.gps_enabled == false) {
|
||||
doGPSpowersave(false);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (config.position.gps_enabled == false)
|
||||
return 0;
|
||||
|
||||
// Repeaters have no need for GPS
|
||||
if (config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER)
|
||||
disable();
|
||||
if (config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER) {
|
||||
return disable();
|
||||
}
|
||||
|
||||
if (whileIdle()) {
|
||||
// if we have received valid NMEA claim we are connected
|
||||
@@ -580,20 +636,27 @@ int32_t GPS::runOnce()
|
||||
} else {
|
||||
if ((config.position.gps_enabled == 1) && (gnssModel == GNSS_MODEL_UBLOX)) {
|
||||
// reset the GPS on next bootup
|
||||
if (devicestate.did_gps_reset && (millis() > 60000) && !hasFlow()) {
|
||||
if (devicestate.did_gps_reset && (millis() - lastWakeStartMsec > 60000) && !hasFlow()) {
|
||||
LOG_DEBUG("GPS is not communicating, trying factory reset on next bootup.\n");
|
||||
devicestate.did_gps_reset = false;
|
||||
nodeDB.saveDeviceStateToDisk();
|
||||
disable(); // Stop the GPS thread as it can do nothing useful until next reboot.
|
||||
return disable(); // Stop the GPS thread as it can do nothing useful until next reboot.
|
||||
}
|
||||
}
|
||||
}
|
||||
// At least one GPS has a bad habit of losing its mind from time to time
|
||||
if (rebootsSeen > 2) {
|
||||
rebootsSeen = 0;
|
||||
gps->factoryReset();
|
||||
}
|
||||
|
||||
// If we are overdue for an update, turn on the GPS and at least publish the current status
|
||||
uint32_t now = millis();
|
||||
uint32_t timeAsleep = now - lastSleepStartMsec;
|
||||
|
||||
auto sleepTime = getSleepTime();
|
||||
if (!isAwake && sleepTime != UINT32_MAX && (now - lastSleepStartMsec) > sleepTime) {
|
||||
if (!isAwake && (sleepTime != UINT32_MAX) &&
|
||||
((timeAsleep > sleepTime) || (isInPowersave && timeAsleep > (sleepTime - averageLockTime)))) {
|
||||
// We now want to be awake - so wake up the GPS
|
||||
setAwake(true);
|
||||
}
|
||||
@@ -601,11 +664,6 @@ int32_t GPS::runOnce()
|
||||
// While we are awake
|
||||
if (isAwake) {
|
||||
// LOG_DEBUG("looking for location\n");
|
||||
if ((now - lastWhileActiveMsec) > 5000) {
|
||||
lastWhileActiveMsec = now;
|
||||
whileActive();
|
||||
}
|
||||
|
||||
// If we've already set time from the GPS, no need to ask the GPS
|
||||
bool gotTime = (getRTCQuality() >= RTCQualityGPS);
|
||||
if (!gotTime && lookForTime()) { // Note: we count on this && short-circuiting and not resetting the RTC time
|
||||
@@ -620,7 +678,6 @@ int32_t GPS::runOnce()
|
||||
shouldPublish = true;
|
||||
}
|
||||
|
||||
// We've been awake too long - force sleep
|
||||
now = millis();
|
||||
auto wakeTime = getWakeTime();
|
||||
bool tooLong = wakeTime != UINT32_MAX && (now - lastWakeStartMsec) > wakeTime;
|
||||
@@ -645,26 +702,15 @@ int32_t GPS::runOnce()
|
||||
|
||||
// If state has changed do a publish
|
||||
publishUpdate();
|
||||
|
||||
if (config.position.fixed_position == true && hasValidLocation)
|
||||
return disable(); // This should trigger when we have a fixed position, and get that first position
|
||||
|
||||
// 9600bps is approx 1 byte per msec, so considering our buffer size we never need to wake more often than 200ms
|
||||
// if not awake we can run super infrquently (once every 5 secs?) to see if we need to wake.
|
||||
return isAwake ? GPS_THREAD_INTERVAL : 5000;
|
||||
}
|
||||
|
||||
void GPS::forceWake(bool on)
|
||||
{
|
||||
if (on) {
|
||||
LOG_DEBUG("Allowing GPS lock\n");
|
||||
// lastSleepStartMsec = 0; // Force an update ASAP
|
||||
wakeAllowed = true;
|
||||
} else {
|
||||
wakeAllowed = false;
|
||||
|
||||
// Note: if the gps was already awake, we DO NOT shut it down, because we want to allow it to complete its lock
|
||||
// attempt even if we are in light sleep. Once the attempt succeeds (or times out) we'll then shut it down.
|
||||
// setAwake(false);
|
||||
}
|
||||
}
|
||||
|
||||
// clear the GPS rx buffer as quickly as possible
|
||||
void GPS::clearBuffer()
|
||||
{
|
||||
@@ -673,22 +719,11 @@ void GPS::clearBuffer()
|
||||
_serial_gps->read();
|
||||
}
|
||||
|
||||
/// Prepare the GPS for the cpu entering deep or light sleep, expect to be gone for at least 100s of msecs
|
||||
int GPS::prepareSleep(void *unused)
|
||||
{
|
||||
LOG_INFO("GPS prepare sleep!\n");
|
||||
forceWake(false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Prepare the GPS for the cpu entering deep or light sleep, expect to be gone for at least 100s of msecs
|
||||
int GPS::prepareDeepSleep(void *unused)
|
||||
{
|
||||
LOG_INFO("GPS deep sleep!\n");
|
||||
|
||||
// For deep sleep we also want abandon any lock attempts (because we want minimum power)
|
||||
getSleepTime();
|
||||
setAwake(false);
|
||||
|
||||
return 0;
|
||||
@@ -833,11 +868,11 @@ GnssModel_t GPS::probe(int serialSpeed)
|
||||
return GNSS_MODEL_UBLOX;
|
||||
}
|
||||
|
||||
// GPS::GPS(uint32_t _rx_gpio, uint32_t _tx_gpio) : concurrency::OSThread("GPS")
|
||||
GPS *GPS::createGps()
|
||||
{
|
||||
int8_t _rx_gpio = config.position.rx_gpio;
|
||||
int8_t _tx_gpio = config.position.tx_gpio;
|
||||
int8_t _en_gpio = config.position.gps_en_gpio;
|
||||
#if defined(HAS_GPS) && !defined(ARCH_ESP32)
|
||||
_rx_gpio = 1; // We only specify GPS serial ports on ESP32. Otherwise, these are just flags.
|
||||
_tx_gpio = 1;
|
||||
@@ -850,12 +885,23 @@ GPS *GPS::createGps()
|
||||
if (!_tx_gpio)
|
||||
_tx_gpio = GPS_TX_PIN;
|
||||
#endif
|
||||
if (!_rx_gpio) // Configured to have no GPS at all
|
||||
#if defined(PIN_GPS_EN)
|
||||
if (!_en_gpio)
|
||||
_en_gpio = PIN_GPS_EN;
|
||||
#endif
|
||||
if (!_rx_gpio || !_serial_gps) // Configured to have no GPS at all
|
||||
return nullptr;
|
||||
|
||||
GPS *new_gps = new GPS;
|
||||
new_gps->rx_gpio = _rx_gpio;
|
||||
new_gps->tx_gpio = _tx_gpio;
|
||||
new_gps->en_gpio = _en_gpio;
|
||||
|
||||
if (_en_gpio != 0) {
|
||||
LOG_DEBUG("Setting %d to output.\n", _en_gpio);
|
||||
digitalWrite(_en_gpio, !GPS_EN_ACTIVE);
|
||||
pinMode(_en_gpio, OUTPUT);
|
||||
}
|
||||
|
||||
#ifdef PIN_GPS_PPS
|
||||
// pulse per second
|
||||
@@ -871,14 +917,7 @@ GPS *GPS::createGps()
|
||||
LOG_DEBUG("Using " NMEA_MSG_GXGSA " for 3DFIX and PDOP\n");
|
||||
#endif
|
||||
|
||||
#if defined(HAS_PMU) || defined(PIN_GPS_EN)
|
||||
if (config.position.gps_enabled) {
|
||||
#ifdef PIN_GPS_EN
|
||||
pinMode(PIN_GPS_EN, OUTPUT);
|
||||
#endif
|
||||
setGPSPower(true);
|
||||
}
|
||||
#endif
|
||||
new_gps->setGPSPower(true, false, 0);
|
||||
|
||||
#ifdef PIN_GPS_RESET
|
||||
digitalWrite(PIN_GPS_RESET, GPS_RESET_MODE); // assert for 10ms
|
||||
@@ -933,11 +972,38 @@ bool GPS::factoryReset()
|
||||
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));
|
||||
if (HW_VENDOR == meshtastic_HardwareModel_TBEAM) {
|
||||
byte _message_reset1[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x1C, 0xA2};
|
||||
_serial_gps->write(_message_reset1, sizeof(_message_reset1));
|
||||
if (getACK(0x05, 0x01, 10000)) {
|
||||
LOG_INFO("Get ack success!\n");
|
||||
}
|
||||
delay(100);
|
||||
byte _message_reset2[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x1B, 0xA1};
|
||||
_serial_gps->write(_message_reset2, sizeof(_message_reset2));
|
||||
if (getACK(0x05, 0x01, 10000)) {
|
||||
LOG_INFO("Get ack success!\n");
|
||||
}
|
||||
delay(100);
|
||||
byte _message_reset3[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0x1D, 0xB3};
|
||||
_serial_gps->write(_message_reset3, sizeof(_message_reset3));
|
||||
if (getACK(0x05, 0x01, 10000)) {
|
||||
LOG_INFO("Get ack success!\n");
|
||||
}
|
||||
// Reset device ram to COLDSTART state
|
||||
// byte _message_CFG_RST_COLDSTART[] = {0xB5, 0x62, 0x06, 0x04, 0x04, 0x00, 0xFF, 0xB9, 0x00, 0x00, 0xC6, 0x8B};
|
||||
// _serial_gps->write(_message_CFG_RST_COLDSTART, sizeof(_message_CFG_RST_COLDSTART));
|
||||
// delay(1000);
|
||||
} else {
|
||||
// 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;
|
||||
}
|
||||
@@ -1134,7 +1200,12 @@ bool GPS::hasFlow()
|
||||
|
||||
bool GPS::whileIdle()
|
||||
{
|
||||
int charsInBuf = 0;
|
||||
bool isValid = false;
|
||||
if (!isAwake) {
|
||||
clearBuffer();
|
||||
return isAwake;
|
||||
}
|
||||
#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());
|
||||
@@ -1146,50 +1217,34 @@ bool GPS::whileIdle()
|
||||
// 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);
|
||||
UBXscratch[charsInBuf] = c;
|
||||
#ifdef GPS_DEBUG
|
||||
LOG_DEBUG("%c", c);
|
||||
#endif
|
||||
isValid |= reader.encode(c);
|
||||
if (charsInBuf > sizeof(UBXscratch) - 10 || c == '\r') {
|
||||
if (strnstr((char *)UBXscratch, "$GPTXT,01,01,02,u-blox ag - www.u-blox.com*50", charsInBuf)) {
|
||||
rebootsSeen++;
|
||||
}
|
||||
charsInBuf = 0;
|
||||
} else {
|
||||
charsInBuf++;
|
||||
}
|
||||
}
|
||||
|
||||
return isValid;
|
||||
}
|
||||
|
||||
void GPS::doGPSpowersave(bool on)
|
||||
void GPS::enable()
|
||||
{
|
||||
#if defined(HAS_PMU) || defined(PIN_GPS_EN)
|
||||
if (on) {
|
||||
LOG_INFO("Turning GPS back on\n");
|
||||
gps->forceWake(1);
|
||||
setGPSPower(1);
|
||||
setAwake(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);
|
||||
setAwake(1);
|
||||
} else {
|
||||
LOG_INFO("GPS entering sleep");
|
||||
notifyGPSSleep.notifyObservers(NULL);
|
||||
}
|
||||
#endif
|
||||
#if !(defined(HAS_PMU) || defined(PIN_GPS_EN) || defined(PIN_GPS_WAKE))
|
||||
if (!on) {
|
||||
notifyGPSSleep.notifyObservers(NULL);
|
||||
if (gnssModel == GNSS_MODEL_UBLOX) {
|
||||
uint8_t msglen;
|
||||
msglen = gps->makeUBXPacket(0x02, 0x41, 0x08, gps->_message_PMREQ);
|
||||
gps->_serial_gps->write(gps->UBXscratch, msglen);
|
||||
}
|
||||
setAwake(1);
|
||||
} else {
|
||||
gps->forceWake(1);
|
||||
if (gnssModel == GNSS_MODEL_UBLOX)
|
||||
gps->_serial_gps->write(0xFF);
|
||||
}
|
||||
#endif
|
||||
enabled = true;
|
||||
setInterval(GPS_THREAD_INTERVAL);
|
||||
setAwake(true);
|
||||
}
|
||||
|
||||
int32_t GPS::disable()
|
||||
{
|
||||
enabled = false;
|
||||
setInterval(INT32_MAX);
|
||||
setAwake(false);
|
||||
|
||||
return INT32_MAX;
|
||||
}
|
||||
@@ -4,6 +4,14 @@
|
||||
#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];
|
||||
@@ -48,11 +56,14 @@ class GPS : private concurrency::OSThread
|
||||
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;
|
||||
@@ -65,7 +76,7 @@ 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()
|
||||
|
||||
@@ -76,7 +87,6 @@ class GPS : private concurrency::OSThread
|
||||
|
||||
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);
|
||||
|
||||
@@ -84,7 +94,7 @@ class GPS : private concurrency::OSThread
|
||||
/** If !NULL we will use this serial port to construct our GPS */
|
||||
static HardwareSerial *_serial_gps;
|
||||
|
||||
static const uint8_t _message_PMREQ[];
|
||||
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[];
|
||||
@@ -116,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();
|
||||
|
||||
@@ -127,14 +145,6 @@ 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);
|
||||
|
||||
// Empty the input buffer as quickly as possible
|
||||
void clearBuffer();
|
||||
|
||||
@@ -144,6 +154,8 @@ class GPS : private concurrency::OSThread
|
||||
// scratch space for creating ublox packets
|
||||
uint8_t UBXscratch[250] = {0};
|
||||
|
||||
int rebootsSeen = 0;
|
||||
|
||||
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);
|
||||
@@ -154,7 +166,6 @@ class GPS : private concurrency::OSThread
|
||||
* calls sleep/wake
|
||||
*/
|
||||
void setAwake(bool on);
|
||||
void doGPSpowersave(bool on);
|
||||
virtual bool factoryReset();
|
||||
|
||||
// Creates an instance of the GPS class.
|
||||
@@ -162,20 +173,6 @@ class GPS : private concurrency::OSThread
|
||||
static GPS *createGps();
|
||||
|
||||
protected:
|
||||
/// If possible force the GPS into sleep/low power mode
|
||||
virtual void sleep();
|
||||
|
||||
/// wake the GPS into normal operation mode
|
||||
virtual void wake();
|
||||
|
||||
/** 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
|
||||
*/
|
||||
|
||||
/** 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
|
||||
@@ -193,8 +190,6 @@ class GPS : private concurrency::OSThread
|
||||
/// Record that we have a GPS
|
||||
void setConnected();
|
||||
|
||||
void setNumSatellites(uint8_t n);
|
||||
|
||||
/** 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
|
||||
@@ -218,10 +213,6 @@ class GPS : private concurrency::OSThread
|
||||
virtual bool lookForLocation();
|
||||
|
||||
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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
const uint8_t GPS::_message_PMREQ[] PROGMEM = {
|
||||
uint8_t GPS::_message_PMREQ[] PROGMEM = {
|
||||
0x00, 0x00, // 4 bytes duration of request task
|
||||
0x00, 0x00, // (milliseconds)
|
||||
0x02, 0x00, // Task flag bitfield
|
||||
@@ -17,7 +17,7 @@ const uint8_t GPS::_message_CFG_RXM_ECO[] PROGMEM = {
|
||||
|
||||
const uint8_t GPS::_message_CFG_PM2[] PROGMEM = {
|
||||
0x01, 0x06, 0x00, 0x00, // version, Reserved
|
||||
0x0e, 0x81, 0x42, 0x01, // flags
|
||||
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
|
||||
@@ -189,4 +189,4 @@ const uint8_t GPS::_message_SAVE[] = {
|
||||
0xFF, 0xFF, 0x00, 0x00, // saveMask: save all sections
|
||||
0x00, 0x00, 0x00, 0x00, // loadMask: no sections loaded
|
||||
0x0F // deviceMask: BBR, Flash, EEPROM, and SPI Flash
|
||||
};
|
||||
};
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "configuration.h"
|
||||
#include "main.h"
|
||||
|
||||
#ifndef TFT_BACKLIGHT_ON
|
||||
#define TFT_BACKLIGHT_ON HIGH
|
||||
@@ -81,8 +82,16 @@ class LGFX : public lgfx::LGFX_Device
|
||||
{
|
||||
auto cfg = _light_instance.config(); // Gets a structure for backlight settings.
|
||||
|
||||
#ifdef ST7735_BL_V03
|
||||
if (heltec_version == 3) {
|
||||
cfg.pin_bl = ST7735_BL_V03;
|
||||
} else {
|
||||
cfg.pin_bl = ST7735_BL_V05;
|
||||
}
|
||||
#else
|
||||
cfg.pin_bl = ST7735_BL; // Pin number to which the backlight is connected
|
||||
cfg.invert = true; // true to invert the brightness of the backlight
|
||||
#endif
|
||||
cfg.invert = true; // true to invert the brightness of the backlight
|
||||
// cfg.freq = 44100; // PWM frequency of backlight
|
||||
// cfg.pwm_channel = 1; // PWM channel number to use
|
||||
|
||||
@@ -364,9 +373,23 @@ void TFTDisplay::sendCommand(uint8_t com)
|
||||
// handle display on/off directly
|
||||
switch (com) {
|
||||
case DISPLAYON: {
|
||||
#if defined(ST7735_BACKLIGHT_EN_V03) && defined(TFT_BACKLIGHT_ON)
|
||||
if (heltec_version == 3) {
|
||||
digitalWrite(ST7735_BACKLIGHT_EN_V03, TFT_BACKLIGHT_ON);
|
||||
} else {
|
||||
digitalWrite(ST7735_BACKLIGHT_EN_V05, TFT_BACKLIGHT_ON);
|
||||
}
|
||||
#endif
|
||||
#if defined(TFT_BL) && defined(TFT_BACKLIGHT_ON)
|
||||
digitalWrite(TFT_BL, TFT_BACKLIGHT_ON);
|
||||
#endif
|
||||
#ifdef VTFT_CTRL_V03
|
||||
if (heltec_version == 3) {
|
||||
digitalWrite(VTFT_CTRL_V03, LOW);
|
||||
} else {
|
||||
digitalWrite(VTFT_CTRL_V05, LOW);
|
||||
}
|
||||
#endif
|
||||
#ifdef VTFT_CTRL
|
||||
digitalWrite(VTFT_CTRL, LOW);
|
||||
#endif
|
||||
@@ -376,9 +399,23 @@ void TFTDisplay::sendCommand(uint8_t com)
|
||||
break;
|
||||
}
|
||||
case DISPLAYOFF: {
|
||||
#if defined(ST7735_BACKLIGHT_EN_V03) && defined(TFT_BACKLIGHT_ON)
|
||||
if (heltec_version == 3) {
|
||||
digitalWrite(ST7735_BACKLIGHT_EN_V03, !TFT_BACKLIGHT_ON);
|
||||
} else {
|
||||
digitalWrite(ST7735_BACKLIGHT_EN_V05, !TFT_BACKLIGHT_ON);
|
||||
}
|
||||
#endif
|
||||
#if defined(TFT_BL) && defined(TFT_BACKLIGHT_ON)
|
||||
digitalWrite(TFT_BL, !TFT_BACKLIGHT_ON);
|
||||
#endif
|
||||
#ifdef VTFT_CTRL_V03
|
||||
if (heltec_version == 3) {
|
||||
digitalWrite(VTFT_CTRL_V03, HIGH);
|
||||
} else {
|
||||
digitalWrite(VTFT_CTRL_V05, HIGH);
|
||||
}
|
||||
#endif
|
||||
#ifdef VTFT_CTRL
|
||||
digitalWrite(VTFT_CTRL, HIGH);
|
||||
#endif
|
||||
@@ -436,6 +473,16 @@ bool TFTDisplay::connect()
|
||||
pinMode(TFT_BL, OUTPUT);
|
||||
#endif
|
||||
|
||||
#ifdef ST7735_BACKLIGHT_EN_V03
|
||||
if (heltec_version == 3) {
|
||||
digitalWrite(ST7735_BACKLIGHT_EN_V03, TFT_BACKLIGHT_ON);
|
||||
pinMode(ST7735_BACKLIGHT_EN_V03, OUTPUT);
|
||||
} else {
|
||||
digitalWrite(ST7735_BACKLIGHT_EN_V05, TFT_BACKLIGHT_ON);
|
||||
pinMode(ST7735_BACKLIGHT_EN_V05, OUTPUT);
|
||||
}
|
||||
#endif
|
||||
|
||||
tft.init();
|
||||
#if defined(M5STACK)
|
||||
tft.setRotation(0);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@ class RotaryEncoderInterruptImpl1 : public RotaryEncoderInterruptBase
|
||||
{
|
||||
public:
|
||||
RotaryEncoderInterruptImpl1();
|
||||
void init();
|
||||
bool init();
|
||||
static void handleIntA();
|
||||
static void handleIntB();
|
||||
static void handleIntPressed();
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
70
src/main.cpp
70
src/main.cpp
@@ -146,6 +146,25 @@ const char *getDeviceName()
|
||||
return name;
|
||||
}
|
||||
|
||||
#ifdef VEXT_ENABLE_V03
|
||||
|
||||
#include <soc/rtc.h>
|
||||
|
||||
static uint32_t calibrate_one(rtc_cal_sel_t cal_clk, const char *name)
|
||||
{
|
||||
const uint32_t cal_count = 1000;
|
||||
uint32_t cali_val;
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
cali_val = rtc_clk_cal(cal_clk, cal_count);
|
||||
}
|
||||
return cali_val;
|
||||
}
|
||||
|
||||
int heltec_version = 3;
|
||||
|
||||
#define CALIBRATE_ONE(cali_clk) calibrate_one(cali_clk, #cali_clk)
|
||||
#endif
|
||||
|
||||
static int32_t ledBlinker()
|
||||
{
|
||||
static bool ledOn;
|
||||
@@ -216,12 +235,59 @@ void setup()
|
||||
digitalWrite(PIN_EINK_PWR_ON, HIGH);
|
||||
#endif
|
||||
|
||||
#ifdef VEXT_ENABLE
|
||||
#ifdef ST7735_BL_V03 // Heltec Wireless Tracker PCB Change Detect/Hack
|
||||
|
||||
rtc_clk_32k_enable(true);
|
||||
CALIBRATE_ONE(RTC_CAL_RTC_MUX);
|
||||
if (CALIBRATE_ONE(RTC_CAL_32K_XTAL) != 0) {
|
||||
rtc_clk_slow_freq_set(RTC_SLOW_FREQ_32K_XTAL);
|
||||
CALIBRATE_ONE(RTC_CAL_RTC_MUX);
|
||||
CALIBRATE_ONE(RTC_CAL_32K_XTAL);
|
||||
}
|
||||
|
||||
if (rtc_clk_slow_freq_get() != RTC_SLOW_FREQ_32K_XTAL) {
|
||||
heltec_version = 3;
|
||||
} else {
|
||||
heltec_version = 5;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(VEXT_ENABLE_V03)
|
||||
if (heltec_version == 3) {
|
||||
pinMode(VEXT_ENABLE_V03, OUTPUT);
|
||||
digitalWrite(VEXT_ENABLE_V03, 0); // turn on the display power
|
||||
LOG_DEBUG("HELTEC Detect Tracker V1.0\n");
|
||||
} else {
|
||||
pinMode(VEXT_ENABLE_V05, OUTPUT);
|
||||
digitalWrite(VEXT_ENABLE_V05, 1); // turn on the display power
|
||||
LOG_DEBUG("HELTEC Detect Tracker V1.1\n");
|
||||
}
|
||||
#elif defined(VEXT_ENABLE)
|
||||
pinMode(VEXT_ENABLE, OUTPUT);
|
||||
digitalWrite(VEXT_ENABLE, 0); // turn on the display power
|
||||
#endif
|
||||
|
||||
#ifdef VGNSS_CTRL
|
||||
#if defined(VGNSS_CTRL_V03)
|
||||
if (heltec_version == 3) {
|
||||
pinMode(VGNSS_CTRL_V03, OUTPUT);
|
||||
digitalWrite(VGNSS_CTRL_V03, LOW);
|
||||
} else {
|
||||
pinMode(VGNSS_CTRL_V05, OUTPUT);
|
||||
digitalWrite(VGNSS_CTRL_V05, LOW);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(VTFT_CTRL_V03)
|
||||
if (heltec_version == 3) {
|
||||
pinMode(VTFT_CTRL_V03, OUTPUT);
|
||||
digitalWrite(VTFT_CTRL_V03, LOW);
|
||||
} else {
|
||||
pinMode(VTFT_CTRL_V05, OUTPUT);
|
||||
digitalWrite(VTFT_CTRL_V05, LOW);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(VGNSS_CTRL)
|
||||
pinMode(VGNSS_CTRL, OUTPUT);
|
||||
digitalWrite(VGNSS_CTRL, LOW);
|
||||
#endif
|
||||
|
||||
@@ -64,6 +64,8 @@ extern uint32_t shutdownAtMsec;
|
||||
|
||||
extern uint32_t serialSinceMsec;
|
||||
|
||||
extern int heltec_version;
|
||||
|
||||
// If a thread does something that might need for it to be rescheduled ASAP it can set this flag
|
||||
// This will suppress the current delay and instead try to run ASAP.
|
||||
extern bool runASAP;
|
||||
|
||||
@@ -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;
|
||||
@@ -679,8 +687,8 @@ void NodeDB::updatePosition(uint32_t nodeId, const meshtastic_Position &p, RxSou
|
||||
LOG_INFO("updatePosition LOCAL pos@%x, time=%u, latI=%d, lonI=%d, alt=%d\n", p.timestamp, p.time, p.latitude_i,
|
||||
p.longitude_i, p.altitude);
|
||||
|
||||
setLocalPosition(p);
|
||||
info->position = ConvertToPositionLite(p);
|
||||
localPosition = p;
|
||||
} else if ((p.time > 0) && !p.latitude_i && !p.longitude_i && !p.timestamp && !p.location_source) {
|
||||
// FIXME SPECIAL TIME SETTING PACKET FROM EUD TO RADIO
|
||||
// (stop-gap fix for issue #900)
|
||||
|
||||
@@ -131,6 +131,13 @@ class NodeDB
|
||||
meshtastic_NodeInfoLite *getMeshNode(NodeNum n);
|
||||
size_t getNumMeshNodes() { return *numMeshNodes; }
|
||||
|
||||
void setLocalPosition(meshtastic_Position position)
|
||||
{
|
||||
LOG_DEBUG("Setting local position: latitude=%i, longitude=%i, time=%i\n", position.latitude_i, position.longitude_i,
|
||||
position.time);
|
||||
localPosition = position;
|
||||
}
|
||||
|
||||
private:
|
||||
/// Find a node in our DB, create an empty NodeInfoLite if missing
|
||||
meshtastic_NodeInfoLite *getOrCreateMeshNode(NodeNum n);
|
||||
@@ -192,7 +199,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"
|
||||
@@ -212,6 +219,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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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\
|
||||
@@ -531,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}
|
||||
@@ -540,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}
|
||||
@@ -559,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
|
||||
@@ -570,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
|
||||
@@ -654,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
|
||||
|
||||
@@ -669,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
|
||||
|
||||
@@ -769,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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -113,6 +113,8 @@ typedef enum _meshtastic_HardwareModel {
|
||||
meshtastic_HardwareModel_PICOMPUTER_S3 = 52,
|
||||
/* Heltec HT-CT62 with ESP32-C3 CPU and SX1262 LoRa */
|
||||
meshtastic_HardwareModel_HELTEC_HT62 = 53,
|
||||
/* E22-900M series modules with ESP32-S3 */
|
||||
meshtastic_HardwareModel_E22_900M_S3 = 54,
|
||||
/* ------------------------------------------------------------------------------------------------------------------------------------------
|
||||
Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits.
|
||||
------------------------------------------------------------------------------------------------------------------------------------------ */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
@@ -27,18 +44,19 @@ bool PositionModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, mes
|
||||
|
||||
// FIXME this can in fact happen with packets sent from EUD (src=RX_SRC_USER)
|
||||
// to set fixed location, EUD-GPS location or just the time (see also issue #900)
|
||||
bool isLocal = false;
|
||||
if (nodeDB.getNodeNum() == getFrom(&mp)) {
|
||||
LOG_DEBUG("Incoming update from MYSELF\n");
|
||||
// LOG_DEBUG("Ignored an incoming update from MYSELF\n");
|
||||
// return false;
|
||||
isLocal = true;
|
||||
nodeDB.setLocalPosition(p);
|
||||
}
|
||||
|
||||
// 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;
|
||||
@@ -47,7 +65,8 @@ bool PositionModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, mes
|
||||
tv.tv_sec = secs;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
perhapsSetRTC(RTCQualityFromNet, &tv);
|
||||
// Set from phone RTC Quality to RTCQualityNTP since it should be approximately so
|
||||
perhapsSetRTC(isLocal ? RTCQualityNTP : RTCQualityFromNet, &tv);
|
||||
}
|
||||
|
||||
nodeDB.updatePosition(getFrom(&mp), p);
|
||||
@@ -77,8 +96,9 @@ meshtastic_MeshPacket *PositionModule::allocReply()
|
||||
|
||||
// Populate a Position struct with ONLY the requested fields
|
||||
meshtastic_Position p = meshtastic_Position_init_default; // Start with an empty structure
|
||||
// if localPosition is totally empty, put our last saved position (lite) in there
|
||||
if (localPosition.latitude_i == 0 && localPosition.longitude_i == 0) {
|
||||
localPosition = ConvertToPosition(node->position);
|
||||
nodeDB.setLocalPosition(ConvertToPosition(node->position));
|
||||
}
|
||||
localPosition.seq_number++;
|
||||
|
||||
@@ -148,7 +168,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,75 +179,142 @@ 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 5 seconds and then going to sleep.\n");
|
||||
sleepOnNextExecution = true;
|
||||
setIntervalFromNow(5000);
|
||||
}
|
||||
}
|
||||
|
||||
#define RUNONCE_INTERVAL 5000;
|
||||
|
||||
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
|
||||
uint32_t now = millis();
|
||||
uint32_t intervalMs = getConfiguredOrDefaultMs(config.position.position_broadcast_secs, default_broadcast_interval_secs);
|
||||
uint32_t msSinceLastSend = now - lastGpsSend;
|
||||
// Only send packets if the channel util. is less than 25% utilized or we're a tracker with less than 40% utilized.
|
||||
if (!airTime->isTxAllowedChannelUtil(config.device.role != meshtastic_Config_DeviceConfig_Role_TRACKER)) {
|
||||
return RUNONCE_INTERVAL;
|
||||
}
|
||||
|
||||
if (lastGpsSend == 0 || msSinceLastSend >= intervalMs) {
|
||||
// Only send packets if the channel is less than 40% utilized.
|
||||
if (airTime->isTxAllowedChannelUtil()) {
|
||||
if (hasValidPosition(node)) {
|
||||
lastGpsSend = now;
|
||||
if (hasValidPosition(node)) {
|
||||
lastGpsSend = now;
|
||||
|
||||
lastGpsLatitude = node->position.latitude_i;
|
||||
lastGpsLongitude = node->position.longitude_i;
|
||||
lastGpsLatitude = node->position.latitude_i;
|
||||
lastGpsLongitude = node->position.longitude_i;
|
||||
|
||||
// If we changed channels, ask everyone else for their latest info
|
||||
// If we changed channels, ask everyone else for their latest info
|
||||
bool requestReplies = currentGeneration != radioGeneration;
|
||||
currentGeneration = radioGeneration;
|
||||
|
||||
LOG_INFO("Sending pos@%x:6 to mesh (wantReplies=%d)\n", localPosition.timestamp, requestReplies);
|
||||
sendOurPosition(NODENUM_BROADCAST, requestReplies);
|
||||
}
|
||||
} else if (config.position.position_broadcast_smart_enabled) {
|
||||
const meshtastic_NodeInfoLite *node2 = service.refreshLocalMeshNode(); // should guarantee there is now a position
|
||||
|
||||
if (hasValidPosition(node2)) {
|
||||
// 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);
|
||||
|
||||
auto smartPosition = getDistanceTraveledSinceLastSend(node->position);
|
||||
|
||||
if (smartPosition.hasTraveledOverThreshold && msSinceLastSend >= minimumTimeThreshold) {
|
||||
bool requestReplies = currentGeneration != radioGeneration;
|
||||
currentGeneration = radioGeneration;
|
||||
|
||||
LOG_INFO("Sending pos@%x:6 to mesh (wantReplies=%d)\n", localPosition.timestamp, requestReplies);
|
||||
LOG_INFO("Sending smart pos@%x:6 to mesh (distanceTraveled=%fm, minDistanceThreshold=%im, timeElapsed=%ims, "
|
||||
"minTimeInterval=%ims)\n",
|
||||
localPosition.timestamp, smartPosition.distanceTraveled, smartPosition.distanceThreshold,
|
||||
msSinceLastSend, minimumTimeThreshold);
|
||||
sendOurPosition(NODENUM_BROADCAST, requestReplies);
|
||||
}
|
||||
}
|
||||
} else if (config.position.position_broadcast_smart_enabled) {
|
||||
// Only send packets if the channel is less than 25% utilized or we're a tracker.
|
||||
if (airTime->isTxAllowedChannelUtil(config.device.role != meshtastic_Config_DeviceConfig_Role_TRACKER)) {
|
||||
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;
|
||||
// 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;
|
||||
|
||||
// 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);
|
||||
|
||||
if ((abs(distanceTraveledSinceLastSend) >= distanceTravelThreshold) && 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,
|
||||
msSinceLastSend, minimumTimeThreshold);
|
||||
sendOurPosition(NODENUM_BROADCAST, requestReplies);
|
||||
|
||||
// Set the current coords as our last ones, after we've compared distance with current and decided to send
|
||||
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;
|
||||
}
|
||||
/* Update lastGpsSend to now. This means if the device is stationary, then
|
||||
getPref_position_broadcast_secs will still apply.
|
||||
*/
|
||||
lastGpsSend = now;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 5000; // to save power only wake for our callback occasionally
|
||||
return RUNONCE_INTERVAL; // 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);
|
||||
|
||||
#ifdef GPS_EXTRAVERBOSE
|
||||
LOG_DEBUG("--------LAST POSITION------------------------------------\n");
|
||||
LOG_DEBUG("lastGpsLatitude=%i, lastGpsLatitude=%i\n", lastGpsLatitude, lastGpsLongitude);
|
||||
|
||||
LOG_DEBUG("--------CURRENT POSITION---------------------------------\n");
|
||||
LOG_DEBUG("currentPosition.latitude_i=%i, currentPosition.longitude_i=%i\n", lastGpsLatitude, lastGpsLongitude);
|
||||
|
||||
LOG_DEBUG("--------SMART POSITION-----------------------------------\n");
|
||||
LOG_DEBUG("hasTraveledOverThreshold=%i, distanceTraveled=%d, distanceThreshold=% u\n",
|
||||
abs(distanceTraveledSinceLastSend) >= distanceTravelThreshold, abs(distanceTraveledSinceLastSend),
|
||||
distanceTravelThreshold);
|
||||
|
||||
if (abs(distanceTraveledSinceLastSend) >= distanceTravelThreshold) {
|
||||
LOG_DEBUG("\n\n\nSMART SEEEEEEEEENDING\n\n\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
@@ -8,6 +8,8 @@
|
||||
#include "configuration.h"
|
||||
#include "main.h"
|
||||
#include "power.h"
|
||||
#include "sleep.h"
|
||||
#include "target_specific.h"
|
||||
#include <OLEDDisplay.h>
|
||||
#include <OLEDDisplayUi.h>
|
||||
|
||||
@@ -51,6 +53,13 @@ SHT31Sensor sht31Sensor;
|
||||
|
||||
int32_t EnvironmentTelemetryModule::runOnce()
|
||||
{
|
||||
if (sleepOnNextExecution == true) {
|
||||
sleepOnNextExecution = false;
|
||||
uint32_t nightyNightMs = getConfiguredOrDefaultMs(moduleConfig.telemetry.environment_update_interval);
|
||||
LOG_DEBUG("Sleeping for %ims, then awaking to send metrics again.\n", nightyNightMs);
|
||||
doDeepSleep(nightyNightMs, true);
|
||||
}
|
||||
|
||||
uint32_t result = UINT32_MAX;
|
||||
/*
|
||||
Uncomment the preferences below if you want to use the module
|
||||
@@ -266,6 +275,12 @@ bool EnvironmentTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
|
||||
} else {
|
||||
LOG_INFO("Sending packet to mesh\n");
|
||||
service.sendToMesh(p, RX_SRC_LOCAL, true);
|
||||
|
||||
if (config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR && config.power.is_power_saving) {
|
||||
LOG_DEBUG("Starting next execution in 5 seconds and then going to sleep.\n");
|
||||
sleepOnNextExecution = true;
|
||||
setIntervalFromNow(5000);
|
||||
}
|
||||
}
|
||||
}
|
||||
return valid;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
@@ -180,14 +180,24 @@ void cpuDeepSleep(uint32_t msecToWake)
|
||||
digitalWrite(AQ_SET_PIN, LOW);
|
||||
#endif
|
||||
#endif
|
||||
// FIXME, use system off mode with ram retention for key state?
|
||||
// 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;
|
||||
// Sleepy trackers or sensors can low power "sleep"
|
||||
// Don't enter this if we're sleeping portMAX_DELAY, since that's a shutdown event
|
||||
if (msecToWake != portMAX_DELAY &&
|
||||
(config.device.role == meshtastic_Config_DeviceConfig_Role_TRACKER ||
|
||||
config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR) &&
|
||||
config.power.is_power_saving == true) {
|
||||
sd_power_mode_set(NRF_POWER_MODE_LOWPWR);
|
||||
delay(msecToWake);
|
||||
NVIC_SystemReset();
|
||||
} else {
|
||||
// FIXME, use system off mode with ram retention for key state?
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
// The following code should not be run, because we are off
|
||||
|
||||
@@ -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,7 +175,7 @@ static void waitEnterSleep()
|
||||
notifySleep.notifyObservers(NULL);
|
||||
}
|
||||
|
||||
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");
|
||||
@@ -192,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
|
||||
@@ -200,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);
|
||||
|
||||
@@ -208,7 +202,13 @@ void doDeepSleep(uint32_t msecToWake)
|
||||
digitalWrite(RESET_OLED, 1); // put the display in reset before killing its power
|
||||
#endif
|
||||
|
||||
#ifdef VEXT_ENABLE
|
||||
#if defined(VEXT_ENABLE_V03)
|
||||
if (heltec_version == 3) {
|
||||
digitalWrite(VEXT_ENABLE_V03, 1); // turn off the display power
|
||||
} else {
|
||||
digitalWrite(VEXT_ENABLE_V05, 0); // turn off the display power
|
||||
}
|
||||
#elif defined(VEXT_ENABLE)
|
||||
digitalWrite(VEXT_ENABLE, 1); // turn off the display power
|
||||
#endif
|
||||
|
||||
@@ -254,7 +254,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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
// Perform power on init that we do on each wake from deep sleep
|
||||
void initDeepSleep();
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -33,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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -9,9 +9,11 @@
|
||||
#define ST7735_RESET 39
|
||||
#define ST7735_MISO -1
|
||||
#define ST7735_BUSY -1
|
||||
#define ST7735_BL 45
|
||||
#define ST7735_BL_V03 45
|
||||
#define ST7735_BL_V05 21 /* V1.1 PCB marking */
|
||||
#define ST7735_SPI_HOST SPI3_HOST
|
||||
#define ST7735_BACKLIGHT_EN 45
|
||||
#define ST7735_BACKLIGHT_EN_V03 45
|
||||
#define ST7735_BACKLIGHT_EN_V05 21
|
||||
#define SPI_FREQUENCY 40000000
|
||||
#define SPI_READ_FREQUENCY 16000000
|
||||
#define SCREEN_ROTATE
|
||||
@@ -19,17 +21,20 @@
|
||||
#define TFT_WIDTH 80
|
||||
#define TFT_OFFSET_X 26
|
||||
#define TFT_OFFSET_Y 0
|
||||
#define VTFT_CTRL 46 // Heltec Tracker needs this pulled low for TFT
|
||||
#define VTFT_CTRL_V03 46 // Heltec Tracker needs this pulled low for TFT
|
||||
#define VTFT_CTRL_V05 -1
|
||||
#define SCREEN_TRANSITION_FRAMERATE 1 // fps
|
||||
#define DISPLAY_FORCE_SMALL_FONTS
|
||||
|
||||
#define VEXT_ENABLE Vext // active low, powers the oled display and the lora antenna boost
|
||||
#define VEXT_ENABLE_V03 Vext // active low, powers the oled display and the lora antenna boost
|
||||
#define VEXT_ENABLE_V05 3 // active HIGH, powers the oled display
|
||||
#define BUTTON_PIN 0
|
||||
|
||||
#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
|
||||
#define ADC_MULTIPLIER 4.9
|
||||
#define ADC_CTRL 2 // active HIGH, powers the voltage divider. Only on 1.1
|
||||
|
||||
#undef GPS_RX_PIN
|
||||
#undef GPS_TX_PIN
|
||||
@@ -37,7 +42,12 @@
|
||||
#define GPS_TX_PIN 34
|
||||
#define PIN_GPS_RESET 35
|
||||
#define PIN_GPS_PPS 36
|
||||
#define VGNSS_CTRL 37 // Heltec Tracker needs this pulled low for GPS
|
||||
|
||||
#define VGNSS_CTRL_V03 37 // Heltec Tracker needs this pulled low for GPS
|
||||
#define VGNSS_CTRL_V05 -1 // Heltec Tracker needs this pulled low for GPS
|
||||
#define PIN_GPS_EN VGNSS_CTRL_V03
|
||||
#define GPS_EN_ACTIVE LOW
|
||||
|
||||
#define GPS_RESET_MODE LOW
|
||||
#define GPS_UC6580
|
||||
|
||||
@@ -57,4 +67,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
|
||||
|
||||
@@ -8,8 +8,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
|
||||
@@ -32,4 +30,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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -48,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
|
||||
|
||||
@@ -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)
|
||||
@@ -275,4 +277,4 @@ SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG
|
||||
* Arduino objects - C++ only
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -17,6 +17,10 @@
|
||||
// SDA = 4
|
||||
// SCL = 5
|
||||
|
||||
// Recommended pins for SerialModule:
|
||||
// txd = 8
|
||||
// rxd = 9
|
||||
|
||||
#define EXT_NOTIFY_OUT 22
|
||||
#define BUTTON_PIN 17
|
||||
|
||||
@@ -49,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
|
||||
|
||||
@@ -17,6 +17,10 @@
|
||||
// SDA = 4
|
||||
// SCL = 5
|
||||
|
||||
// Recommended pins for SerialModule:
|
||||
// txd = 8
|
||||
// rxd = 9
|
||||
|
||||
#define EXT_NOTIFY_OUT 22
|
||||
#define BUTTON_PIN 17
|
||||
|
||||
@@ -47,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
|
||||
|
||||
@@ -27,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
|
||||
@@ -49,4 +47,4 @@
|
||||
|
||||
// Station may not have GPS installed, but it has a labeled GPS pinout
|
||||
#define GPS_RX_PIN 34
|
||||
#define GPS_TX_PIN 12
|
||||
#define GPS_TX_PIN 12
|
||||
|
||||
@@ -8,6 +8,7 @@ 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}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -85,9 +85,9 @@ static const uint8_t A0 = PIN_A0;
|
||||
/*
|
||||
No longer populated on PCB
|
||||
*/
|
||||
//#define PIN_SERIAL2_RX (0 + 6)
|
||||
//#define PIN_SERIAL2_TX (0 + 8)
|
||||
// #define PIN_SERIAL2_EN (0 + 17)
|
||||
// #define PIN_SERIAL2_RX (0 + 6)
|
||||
// #define PIN_SERIAL2_TX (0 + 8)
|
||||
// #define PIN_SERIAL2_EN (0 + 17)
|
||||
|
||||
/**
|
||||
Wire Interfaces
|
||||
@@ -133,7 +133,9 @@ External serial flash WP25R1635FZUIL0
|
||||
// CPU?
|
||||
#define SX126X_BUSY (0 + 17)
|
||||
#define SX126X_RESET (0 + 25)
|
||||
#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)
|
||||
|
||||
@@ -171,7 +173,7 @@ External serial flash WP25R1635FZUIL0
|
||||
#define GPS_L76K
|
||||
#define PIN_GPS_REINIT (32 + 5) // An output to reset L76K GPS. As per datasheet, low for > 100ms will reset the L76K
|
||||
|
||||
#define PIN_GPS_WAKE (32 + 2) // An output to wake GPS, low means allow sleep, high means force wake
|
||||
#define PIN_GPS_STANDBY (32 + 2) // An output to wake GPS, low means allow sleep, high means force wake
|
||||
// Seems to be missing on this new board
|
||||
// #define PIN_GPS_PPS (32 + 4) // Pulse per second input from the GPS
|
||||
#define PIN_GPS_TX (32 + 9) // This is for bits going TOWARDS the CPU
|
||||
|
||||
@@ -63,6 +63,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
|
||||
// Internally the TTGO module hooks the SX1262-DIO2 in to control the TX/RX switch (which is the default for
|
||||
// the sx1262interface code)
|
||||
// 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)
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
#define I2C_SCL 18 // For QMC6310 sensors and screens
|
||||
|
||||
#define BUTTON_PIN 0 // The middle button GPIO on the T-Beam S3
|
||||
//#define BUTTON_PIN_ALT 13 // Alternate GPIO for an external button if needed. Does anyone use this? It is not documented
|
||||
// anywhere.
|
||||
// #define EXT_NOTIFY_OUT 13 // Default pin to use for Ext Notify Module.
|
||||
// #define BUTTON_PIN_ALT 13 // Alternate GPIO for an external button if needed. Does anyone use this? It is not documented
|
||||
// anywhere.
|
||||
// #define EXT_NOTIFY_OUT 13 // Default pin to use for Ext Notify Module.
|
||||
|
||||
#define LED_INVERTED 1
|
||||
|
||||
@@ -29,7 +29,9 @@
|
||||
#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)
|
||||
#endif
|
||||
@@ -64,4 +66,4 @@
|
||||
// has 32768 Hz crystal
|
||||
#define HAS_32768HZ
|
||||
|
||||
#define USE_SH1106
|
||||
#define USE_SH1106
|
||||
|
||||
@@ -28,7 +28,9 @@
|
||||
#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)
|
||||
#endif
|
||||
@@ -39,4 +41,5 @@
|
||||
#define HAS_AXP192
|
||||
#define GPS_UBLOX
|
||||
#define GPS_RX_PIN 34
|
||||
#define GPS_TX_PIN 12
|
||||
#define GPS_TX_PIN 12
|
||||
// #define GPS_DEBUG
|
||||
@@ -1,8 +1,3 @@
|
||||
#undef GPS_RX_PIN
|
||||
#undef GPS_TX_PIN
|
||||
|
||||
#define PIN_GPS_EN 42 // GPS power enable pin
|
||||
|
||||
#define HAS_SDCARD
|
||||
#define SDCARD_USE_SPI1
|
||||
|
||||
@@ -49,7 +44,8 @@
|
||||
#define SX126X_DIO1 33
|
||||
#define SX126X_BUSY 34
|
||||
#define SX126X_RESET LORA_RESET
|
||||
#define SX126X_E22
|
||||
#define SX126X_DIO2_AS_RF_SWITCH
|
||||
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
|
||||
#endif
|
||||
|
||||
// per SX128x_Receive_Interrupt/utilities.h
|
||||
@@ -63,4 +59,4 @@
|
||||
#define SX128X_RXEN 21
|
||||
#define SX128X_TXEN 10
|
||||
#define SX128X_MAX_POWER 3
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
#undef GPS_RX_PIN
|
||||
#undef GPS_TX_PIN
|
||||
|
||||
#define I2C_SDA 4 // I2C pins for this board
|
||||
#define I2C_SCL 15
|
||||
|
||||
@@ -16,4 +13,4 @@
|
||||
#define LORA_DIO0 26 // a No connect on the SX1262 module
|
||||
#define LORA_RESET 14
|
||||
#define LORA_DIO1 33 // Must be manually wired: https://www.thethingsnetwork.org/forum/t/big-esp32-sx127x-topic-part-3/18436
|
||||
#define LORA_DIO2 32 // Not really used
|
||||
#define LORA_DIO2 32 // Not really used
|
||||
@@ -1,8 +1,3 @@
|
||||
#undef GPS_RX_PIN
|
||||
#undef GPS_TX_PIN
|
||||
#define GPS_RX_PIN 36
|
||||
#define GPS_TX_PIN 13 // per @eugene
|
||||
|
||||
#define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
|
||||
#define ADC_CHANNEL ADC1_GPIO35_CHANNEL
|
||||
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
#undef GPS_RX_PIN
|
||||
#undef GPS_TX_PIN
|
||||
#define GPS_RX_PIN 36
|
||||
#define GPS_TX_PIN 13 // per @eugene
|
||||
|
||||
#define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
|
||||
#define ADC_CHANNEL ADC1_GPIO35_CHANNEL
|
||||
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
#undef GPS_RX_PIN
|
||||
#undef GPS_TX_PIN
|
||||
#define GPS_RX_PIN 15 // per @der_bear on the forum, 36 is incorrect for this board type and 15 is a better pick
|
||||
#define GPS_TX_PIN 13
|
||||
|
||||
#define PIN_GPS_EN 19 // GPS power enable pin
|
||||
|
||||
#define BATTERY_PIN 35
|
||||
#define ADC_CHANNEL ADC1_GPIO35_CHANNEL
|
||||
#define BATTERY_SENSE_SAMPLES 30
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
#undef GPS_RX_PIN
|
||||
#undef GPS_TX_PIN
|
||||
|
||||
#define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
|
||||
// ratio of voltage divider = 2.0 (R42=100k, R43=100k)
|
||||
#define ADC_MULTIPLIER 2.11 // 2.0 + 10% for correction of display undervoltage.
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#define VARIANT_MCK (64000000ul)
|
||||
|
||||
#define USE_LFXO // Board uses 32khz crystal for LF
|
||||
//#define USE_LFRC // Board uses RC for LF
|
||||
// #define USE_LFRC // Board uses RC for LF
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
@@ -125,7 +125,6 @@ static const uint8_t SCK = PIN_SPI_SCK;
|
||||
|
||||
#define SX126X_TXEN RADIOLIB_NC
|
||||
#define SX126X_RXEN D7
|
||||
#define E22_TXEN_CONNECTED_TO_DIO2
|
||||
|
||||
// ------------------------------ OR ------------------------------
|
||||
|
||||
@@ -141,7 +140,8 @@ static const uint8_t SCK = PIN_SPI_SCK;
|
||||
#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_DIO2_AS_RF_SWITCH
|
||||
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -198,4 +198,4 @@ static const uint8_t SCL = PIN_WIRE_SCL;
|
||||
* Arduino objects - C++ only
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user