Compare commits

...

39 Commits

Author SHA1 Message Date
Ben Meadors
23272daffe Threshold based smart position broadcasts (#2388)
* Overhaul smart broadcast with new thresholds

* Fixed badly spelt protos

* That's not the right thing

* Format specifiers

* Fmt

* Units

* Default distance threshold of 100
2023-03-27 14:09:22 -05:00
Dan Fay
1af7e48136 Fixed the semi-silent failure to regenerate protobufs on Linux (#2383)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-03-27 06:52:48 -05:00
lewishe
eda00b7b9c Change to Variation Macro Definition 2023-03-27 11:27:57 +02:00
Thomas Göttgens
1898fe850e trunk format 2023-03-27 11:27:57 +02:00
lewishe
15dbe5da97 Added t-beam v1.2 support 2023-03-27 11:27:57 +02:00
GUVWAF
8f736c8ecc Remove sending network ping to displayed node on interval 2023-03-26 16:16:01 +02:00
Thomas Göttgens
8a81f190b8 Merge pull request #2386 from meshtastic/channel-num-fix
fix channel num in json output
2023-03-25 20:35:20 +01:00
Thomas Göttgens
1425657a3c fix channel num in json output 2023-03-25 20:14:04 +01:00
Thomas Göttgens
02041cb605 Merge pull request #2385 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2023-03-25 14:56:33 +01:00
caveman99
1f130d671b [create-pull-request] automated change 2023-03-25 13:38:35 +00:00
Thomas Göttgens
d62e56f428 Merge pull request #2381 from meshtastic/HPD17-PA
Add Power Restraint for 1280 PA Model
2023-03-25 14:24:02 +01:00
Thomas Göttgens
5ac24bb33b Update SX128xInterface.cpp 2023-03-25 14:23:30 +01:00
Thomas Göttgens
2c259b8464 Add Power Restraint for 1280 PA Model
Add Debug Print for all module parameters
Add RX/TX Switch to 1280
2023-03-24 16:57:30 +01:00
github-actions[bot]
9d6e1ce8e5 [create-pull-request] automated change (#2375)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-03-23 13:13:47 -05:00
code8buster
958d2cf630 Remove call to randomSeed() (#2374)
This function causes the new arduino-esp32 core to revert to the pseudorandom behavior specified in Arduino.
Calls to random() automatically use esp_random() if randomSeed or useRealRandomGenerator(false) aren't called.
Tentative fix for #2357
2023-03-23 12:05:12 -05:00
Ben Meadors
5cb1f96240 Use accelerometer to wake up screen (#2371)
* WIP accelerometer tinkering

* Debug logging

* RAK LIS3DH sensor

* Deconflict temperature sensor and LIS3DH

* Finishing up

* StateON

* Protobufs

* Default of none

* Formatting
2023-03-23 11:32:04 -05:00
Thomas Göttgens
78522e750c Merge pull request #2304 from meshtastic/ESP32C3-RISC
ESP32C3 RISC SOC
2023-03-21 17:21:31 +01:00
Thomas Göttgens
75db8c2d2e the target starts up and works for a few seconds before crashing. Good enough for others to continue the work :-) 2023-03-21 16:24:24 +01:00
Thomas Göttgens
91be22b341 Merge branch 'master' into ESP32C3-RISC 2023-03-21 09:31:30 +01:00
github-actions[bot]
36b00dba86 [create-pull-request] automated change (#2367)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-03-18 08:47:40 -05:00
GUVWAF
8c68d888c8 SX126x: Try next Interface when chip not found (#2363)
* If chip was not found, return false for init()

* SX1268: Only overwrite frequency when out of bounds
Happens when region is still UNSET
2023-03-18 07:23:37 -05:00
Manuel
1f99d4756a Fix: Sporadig crashes and reboot (#2366)
* Fix: Sporadig crashes with reboot

* Revert "Fix: Sporadig crashes with reboot"

This reverts commit 59b65749f5.

* Fix: Sporadig crashes and reboot
2023-03-17 19:53:29 -05:00
Andre K
7bbfa48b5d fix channel_num log (#2361)
* fix channel_num variable

* fix channel_num log instead
2023-03-17 13:36:10 -05:00
Manuel
b398f31b64 Fix heap leak mentioned in #2358 (#2359)
* Fix heap leak mentioned in #2358

* Additional fix for #2359
2023-03-14 16:50:32 -05:00
rcarteraz
e03a2f8f7f Add V3 and TBeam S3 to hardware 2023-03-13 19:15:38 -03:00
github-actions[bot]
d92a003d8e [create-pull-request] automated change (#2354)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-03-13 14:07:28 -05:00
Thomas Göttgens
3c2e615650 Merge branch 'master' into ESP32C3-RISC 2023-03-12 20:22:38 +01:00
Thomas Göttgens
4573db4665 Merge branch 'master' into ESP32C3-RISC 2023-03-12 20:19:43 +01:00
Thomas Göttgens
a95b6aff01 Merge branch 'master' into ESP32C3-RISC 2023-03-05 14:55:30 +01:00
Thomas Göttgens
b249970a12 add rudimentary exception decoder for RISC-V CPU 2023-03-05 14:55:12 +01:00
Thomas Göttgens
fe926eedba Merge branch 'ESP32C3-RISC' of github.com:meshtastic/firmware into ESP32C3-RISC 2023-03-04 23:17:56 +01:00
Thomas Göttgens
4355f51a90 fmt 2023-03-04 17:25:55 +01:00
Thomas Göttgens
ecd67f0a85 disable the frequency switcher for the C3 CPU... 2023-03-04 17:25:55 +01:00
Thomas Göttgens
0940c6462b Leaving this here in case someone ever needs int :-) 2023-03-04 17:25:55 +01:00
Thomas Göttgens
a3f1e53017 fmt 2023-02-24 09:53:25 +01:00
Thomas Göttgens
0243922d64 Merge branch 'ESP32C3-RISC' of github.com:meshtastic/firmware into ESP32C3-RISC 2023-02-24 09:32:43 +01:00
Thomas Göttgens
baeb2807a4 disable the frequency switcher for the C3 CPU... 2023-02-24 09:32:31 +01:00
Thomas Göttgens
9a8bfa113d Leaving this here in case someone ever needs int :-) 2023-02-23 22:55:50 +01:00
Thomas Göttgens
82b14fe07c Leaving this here in case someone ever needs int :-) 2023-02-23 22:54:07 +01:00
44 changed files with 508 additions and 115 deletions

View File

@@ -32,6 +32,7 @@ body:
options:
- Not Applicable
- T-Beam
- T-Beam S3
- T-Beam 0.7
- T-Lora v1
- T-Lora v1.3
@@ -42,6 +43,7 @@ body:
- Heltec v1
- Heltec v2
- Heltec v2.1
- Heltec V3
- Relay v1
- Relay v2
- DIY

45
arch/esp32/esp32c3.ini Normal file
View File

@@ -0,0 +1,45 @@
[esp32c3_base]
extends = arduino_base
platform = platformio/espressif32@^6.1.0
build_src_filter =
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2040> -<mesh/eth/>
upload_speed = 961200
monitor_speed = 115200
debug_init_break = tbreak setup
monitor_filters = esp32_c3_exception_decoder
board_build.filesystem = littlefs
# Remove -DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL for low level BLE logging.
# See library directory for BLE logging possible values: .pio/libdeps/tbeam/NimBLE-Arduino/src/log_common/log_common.h
# This overrides the BLE logging default of LOG_LEVEL_INFO (1) from: .pio/libdeps/tbeam/NimBLE-Arduino/src/esp_nimble_cfg.h
build_flags =
${arduino_base.build_flags}
-Wall
-Wextra
-Isrc/platform/esp32
-std=c++11
-DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG
-DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
-DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL
-DCONFIG_BT_NIMBLE_ENABLED
-DCONFIG_NIMBLE_CPP_LOG_LEVEL=2
-DCONFIG_BT_NIMBLE_MAX_CCCDS=20
-DESP_OPENSSL_SUPPRESS_LEGACY_WARNING
;-DDEBUG_HEAP
lib_deps =
${arduino_base.lib_deps}
${networking_base.lib_deps}
${environmental_base.lib_deps}
https://github.com/meshtastic/esp32_https_server.git#23665b3adc080a311dcbb586ed5941b5f94d6ea2
h2zero/NimBLE-Arduino@^1.4.0
https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6
caveman99/ESP32 Codec2@^1.0.1
lib_ignore =
segger_rtt
ESP32 BLE Arduino
; customize the partition table
; http://docs.platformio.org/en/latest/platforms/espressif32.html#partition-tables
board_build.partitions = partition-table.csv

View File

@@ -8,7 +8,7 @@ echo "prebuilt binaries for your computer into nanopb-0.4.7"
# the nanopb tool seems to require that the .options file be in the current directory!
cd protobufs
../nanopb-0.4.7/generator-bin/protoc --nanopb_out=-v:../src/mesh/generated/ -I=../protobufs meshtastic/*.proto
../nanopb-0.4.7/generator-bin/protoc --nanopb_out=-v:../src/mesh/generated/ -I=../protobufs meshtastic/*.proto --experimental_allow_proto3_optional
# cd ../src/mesh/generated/meshtastic
# sed -i 's/#include "meshtastic/#include "./g' -- *

View File

@@ -0,0 +1,155 @@
# Copyright (c) 2014-present PlatformIO <contact@platformio.org>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import re
import subprocess
import sys
from platformio.project.exception import PlatformioException
from platformio.public import (
DeviceMonitorFilterBase,
load_build_metadata,
)
# By design, __init__ is called inside miniterm and we can't pass context to it.
# pylint: disable=attribute-defined-outside-init
IS_WINDOWS = sys.platform.startswith("win")
class Esp32C3ExceptionDecoder(DeviceMonitorFilterBase):
NAME = "esp32_c3_exception_decoder"
PCADDR_PATTERN = re.compile(r'0x4[0-9a-f]{7}', re.IGNORECASE)
def __call__(self):
self.buffer = ""
self.pcaddr_re = self.PCADDR_PATTERN
self.firmware_path = None
self.addr2line_path = None
self.enabled = self.setup_paths()
if self.config.get("env:" + self.environment, "build_type") != "debug":
print(
"""
Please build project in debug configuration to get more details about an exception.
See https://docs.platformio.org/page/projectconf/build_configurations.html
"""
)
return self
def setup_paths(self):
self.project_dir = os.path.abspath(self.project_dir)
try:
data = load_build_metadata(self.project_dir, self.environment)
self.firmware_path = data["prog_path"]
if not os.path.isfile(self.firmware_path):
sys.stderr.write(
"%s: disabling, firmware at %s does not exist, rebuild the project?\n"
% (self.__class__.__name__, self.firmware_path)
)
return False
if self.addr2line_path is None:
cc_path = data.get("cc_path", "")
if "-gcc" in cc_path:
self.addr2line_path = cc_path.replace("-gcc", "-addr2line")
else:
sys.stderr.write(
"%s: disabling, failed to find addr2line.\n"
% self.__class__.__name__
)
return False
if not os.path.isfile(self.addr2line_path):
sys.stderr.write(
"%s: disabling, addr2line at %s does not exist\n"
% (self.__class__.__name__, self.addr2line_path)
)
return False
return True
except PlatformioException as e:
sys.stderr.write(
"%s: disabling, exception while looking for addr2line: %s\n"
% (self.__class__.__name__, e)
)
return False
def rx(self, text):
if not self.enabled:
return text
last = 0
while True:
idx = text.find("\n", last)
if idx == -1:
if len(self.buffer) < 4096:
self.buffer += text[last:]
break
line = text[last:idx]
if self.buffer:
line = self.buffer + line
self.buffer = ""
last = idx + 1
# Output each trace on a separate line below ours
# Logic identical to https://github.com/espressif/esp-idf/blob/master/tools/idf_monitor_base/logger.py#L131
for m in re.finditer(self.pcaddr_re, line):
if m is None:
continue
trace = self.get_backtrace(m)
if len(trace) != "":
text = text[: last] + trace + text[last :]
last += len(trace)
return text
def get_backtrace(self, match):
trace = "\n"
enc = "mbcs" if IS_WINDOWS else "utf-8"
args = [self.addr2line_path, u"-fipC", u"-e", self.firmware_path]
try:
addr = match.group()
output = (
subprocess.check_output(args + [addr])
.decode(enc)
.strip()
)
output = output.replace(
"\n", "\n "
) # newlines happen with inlined methods
output = self.strip_project_dir(output)
# Output the trace in yellow color so that it is easier to spot
trace += "\033[33m=> %s: %s\033[0m\n" % (addr, output)
except subprocess.CalledProcessError as e:
sys.stderr.write(
"%s: failed to call %s: %s\n"
% (self.__class__.__name__, self.addr2line_path, e)
)
return trace
def strip_project_dir(self, trace):
while True:
idx = trace.find(self.project_dir)
if idx == -1:
break
trace = trace[:idx] + trace[idx + len(self.project_dir) + 1 :]
return trace

View File

@@ -111,3 +111,5 @@ lib_deps =
adafruit/Adafruit LPS2X@^2.0.4
adafruit/Adafruit SHT31 Library@^2.2.0
adafruit/Adafruit PM25 AQI Sensor@^1.0.6
adafruit/Adafruit MPU6050@^2.2.4
adafruit/Adafruit LIS3DH@^1.2.4

67
src/AccelerometerThread.h Normal file
View File

@@ -0,0 +1,67 @@
#include "PowerFSM.h"
#include "concurrency/OSThread.h"
#include "configuration.h"
#include "main.h"
#include "power.h"
#include <Adafruit_LIS3DH.h>
#include <Adafruit_MPU6050.h>
namespace concurrency
{
class AccelerometerThread : public concurrency::OSThread
{
public:
AccelerometerThread(ScanI2C::DeviceType type = ScanI2C::DeviceType::NONE) : OSThread("AccelerometerThread")
{
if (accelerometer_found.port == ScanI2C::I2CPort::NO_I2C || !config.display.wake_on_tap_or_motion) {
disable();
return;
}
accleremoter_type = type;
LOG_DEBUG("AccelerometerThread initializing\n");
if (accleremoter_type == ScanI2C::DeviceType::MPU6050 && mpu.begin(accelerometer_found.address)) {
LOG_DEBUG("MPU6050 initializing\n");
// setup motion detection
mpu.setHighPassFilter(MPU6050_HIGHPASS_0_63_HZ);
mpu.setMotionDetectionThreshold(1);
mpu.setMotionDetectionDuration(20);
mpu.setInterruptPinLatch(true); // Keep it latched. Will turn off when reinitialized.
mpu.setInterruptPinPolarity(true);
} else if (accleremoter_type == ScanI2C::DeviceType::LIS3DH && lis.begin(accelerometer_found.address)) {
LOG_DEBUG("LIS3DH initializing\n");
lis.setRange(LIS3DH_RANGE_2_G);
// Adjust threshhold, higher numbers are less sensitive
lis.setClick(1, 80);
}
}
protected:
int32_t runOnce() override
{
canSleep = true; // Assume we should not keep the board awake
if (accleremoter_type == ScanI2C::DeviceType::MPU6050 && mpu.getMotionInterruptStatus()) {
wakeScreen();
} else if (accleremoter_type == ScanI2C::DeviceType::LIS3DH && lis.getClick() > 0) {
wakeScreen();
}
return 100;
}
private:
void wakeScreen()
{
LOG_DEBUG("Tap or motion detected. Turning on screen\n");
if (powerFSM.getState() == &stateDARK) {
powerFSM.trigger(EVENT_INPUT);
}
}
ScanI2C::DeviceType accleremoter_type;
Adafruit_MPU6050 mpu;
Adafruit_LIS3DH lis;
};
} // namespace concurrency

View File

@@ -527,8 +527,39 @@ bool Power::axpChipInit()
} else if (PMU->getChipModel() == XPOWERS_AXP2101) {
// t-beam s3 core
/*The alternative version of T-Beam 1.1 differs from T-Beam V1.1 in that it uses an AXP2101 power chip*/
#if (HW_VENDOR == meshtastic_HardwareModel_TBEAM)
// Unuse power channel
PMU->disablePowerOutput(XPOWERS_DCDC2);
PMU->disablePowerOutput(XPOWERS_DCDC3);
PMU->disablePowerOutput(XPOWERS_DCDC4);
PMU->disablePowerOutput(XPOWERS_DCDC5);
PMU->disablePowerOutput(XPOWERS_ALDO1);
PMU->disablePowerOutput(XPOWERS_ALDO4);
PMU->disablePowerOutput(XPOWERS_BLDO1);
PMU->disablePowerOutput(XPOWERS_BLDO2);
PMU->disablePowerOutput(XPOWERS_DLDO1);
PMU->disablePowerOutput(XPOWERS_DLDO2);
// GNSS RTC PowerVDD 3300mV
PMU->setPowerChannelVoltage(XPOWERS_VBACKUP, 3300);
PMU->enablePowerOutput(XPOWERS_VBACKUP);
// ESP32 VDD 3300mV
// ! No need to set, automatically open , Don't close it
// PMU->setPowerChannelVoltage(XPOWERS_DCDC1, 3300);
// PMU->setProtectedChannel(XPOWERS_DCDC1);
// LoRa VDD 3300mV
PMU->setPowerChannelVoltage(XPOWERS_ALDO2, 3300);
PMU->enablePowerOutput(XPOWERS_ALDO2);
// GNSS VDD 3300mV
PMU->setPowerChannelVoltage(XPOWERS_ALDO3, 3300);
PMU->enablePowerOutput(XPOWERS_ALDO3);
#elif (HW_VENDOR == meshtastic_HardwareModel_LILYGO_TBEAM_S3_CORE)
// t-beam s3 core
/**
* gnss module power channel
* The default ALDO4 is off, you need to turn on the GNSS power first, otherwise it will be invalid during initialization
@@ -571,6 +602,8 @@ bool Power::axpChipInit()
PMU->disablePowerOutput(XPOWERS_DLDO2); // Invalid power channel, it does not exist
PMU->disablePowerOutput(XPOWERS_VBACKUP);
#endif
// disable all axp chip interrupt
PMU->disableIRQ(XPOWERS_AXP2101_ALL_IRQ);

View File

@@ -194,17 +194,6 @@ static void onEnter()
LOG_INFO("Enter state: ON\n");
screen->setOn(true);
setBluetoothEnable(true);
static uint32_t lastPingMs;
uint32_t now = millis();
if ((now - lastPingMs) >
30 * 1000) { // if more than a minute since our last press, ask node we are looking at to update their state
if (displayedNodeNum)
service.sendNetworkPing(displayedNodeNum, true); // Refresh the currently displayed node
lastPingMs = now;
}
}
static void onIdle()

View File

@@ -23,6 +23,6 @@
#define EVENT_INPUT 17 // input broker wants something, we need to wake up and enable screen
extern Fsm powerFSM;
extern State statePOWER, stateSERIAL;
extern State stateON, statePOWER, stateSERIAL, stateDARK;
void PowerFSM_setup();

View File

@@ -82,7 +82,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// #define DISABLE_NTP
// Disable the welcome screen and allow
//#define DISABLE_WELCOME_UNSET
// #define DISABLE_WELCOME_UNSET
// -----------------------------------------------------------------------------
// OLED & Input
@@ -93,7 +93,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// The SH1106 controller is almost, but not quite, the same as SSD1306
// Define this if you know you have that controller or your "SSD1306" misbehaves.
//#define USE_SH1106
// #define USE_SH1106
// Define if screen should be mirrored left to right
// #define SCREEN_MIRROR
@@ -118,6 +118,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define SHT31_ADDR 0x44
#define PMSA0031_ADDR 0x12
// -----------------------------------------------------------------------------
// ACCELEROMETER
// -----------------------------------------------------------------------------
#define MPU6050_ADDR 0x68
#define LIS3DH_ADR 0x18
// -----------------------------------------------------------------------------
// Security
// -----------------------------------------------------------------------------

View File

@@ -34,6 +34,12 @@ ScanI2C::FoundDevice ScanI2C::firstKeyboard() const
return firstOfOrNONE(2, types);
}
ScanI2C::FoundDevice ScanI2C::firstAccelerometer() const
{
ScanI2C::DeviceType types[] = {MPU6050, LIS3DH};
return firstOfOrNONE(2, types);
}
ScanI2C::FoundDevice ScanI2C::find(ScanI2C::DeviceType) const
{
return DEVICE_NONE;

View File

@@ -31,6 +31,8 @@ class ScanI2C
QMI8658,
QMC5883L,
PMSA0031,
MPU6050,
LIS3DH,
} DeviceType;
// typedef uint8_t DeviceAddress;
@@ -79,6 +81,8 @@ class ScanI2C
FoundDevice firstKeyboard() const;
FoundDevice firstAccelerometer() const;
virtual FoundDevice find(DeviceType) const;
virtual bool exists(DeviceType) const;

View File

@@ -248,7 +248,17 @@ void ScanI2CTwoWire::scanPort(I2CPort port)
}
break;
SCAN_SIMPLE_CASE(MCP9808_ADDR, MCP9808, "MCP9808 sensor found\n")
case MCP9808_ADDR:
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x07), 2);
if (registerValue == 0x0400) {
type = MCP9808;
LOG_INFO("MCP9808 sensor found\n");
} else {
type = LIS3DH;
LOG_INFO("LIS3DH accelerometer found\n");
}
break;
SCAN_SIMPLE_CASE(SHT31_ADDR, SHT31, "SHT31 sensor found\n")
SCAN_SIMPLE_CASE(SHTC3_ADDR, SHTC3, "SHTC3 sensor found\n")
@@ -261,11 +271,11 @@ void ScanI2CTwoWire::scanPort(I2CPort port)
SCAN_SIMPLE_CASE(QMC5883L_ADDR, QMC5883L, "QMC5883L Highrate 3-Axis magnetic sensor found\n")
SCAN_SIMPLE_CASE(PMSA0031_ADDR, PMSA0031, "PMSA0031 air quality sensor found\n")
SCAN_SIMPLE_CASE(MPU6050_ADDR, MPU6050, "MPU6050 accelerometer found\n");
default:
LOG_INFO("Device found at address 0x%x was not able to be enumerated\n", addr.address);
}
} else if (err == 4) {
LOG_ERROR("Unknown error at address 0x%x\n", addr);
}

View File

@@ -348,8 +348,6 @@ static void drawFrameFirmware(OLEDDisplay *display, OLEDDisplayUiState *state, i
/// Draw the last text message we received
static void drawCriticalFaultFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
displayedNodeNum = 0; // Not currently showing a node pane
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(FONT_MEDIUM);
@@ -370,8 +368,6 @@ static bool shouldDrawMessage(const meshtastic_MeshPacket *packet)
/// Draw the last text message we received
static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
displayedNodeNum = 0; // Not currently showing a node pane
// the max length of this buffer is much longer than we can possibly print
static char tempBuf[237];
@@ -773,7 +769,6 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
nodeIndex = (nodeIndex + 1) % nodeDB.getNumNodes();
n = nodeDB.getNodeByIndex(nodeIndex);
}
displayedNodeNum = n->num;
}
meshtastic_NodeInfo *node = nodeDB.getNodeByIndex(nodeIndex);
@@ -1393,8 +1388,6 @@ void Screen::setFastFramerate()
void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
displayedNodeNum = 0; // Not currently showing a node pane
display->setFont(FONT_SMALL);
// The coordinates define the left starting point of the text
@@ -1502,8 +1495,6 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i
#if HAS_WIFI
const char *wifiName = config.network.wifi_ssid;
displayedNodeNum = 0; // Not currently showing a node pane
display->setFont(FONT_SMALL);
// The coordinates define the left starting point of the text
@@ -1634,8 +1625,6 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i
void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
displayedNodeNum = 0; // Not currently showing a node pane
display->setFont(FONT_SMALL);
// The coordinates define the left starting point of the text

View File

@@ -68,6 +68,10 @@ NRF52Bluetooth *nrf52Bluetooth;
#endif
#include "PowerFSMThread.h"
#if !defined(ARCH_PORTDUINO)
#include "AccelerometerThread.h"
#endif
using namespace concurrency;
// We always create a screen object, but we only init it if we find the hardware
@@ -94,6 +98,8 @@ uint8_t kb_model;
// The I2C address of the RTC Module (if found)
ScanI2C::DeviceAddress rtc_found = ScanI2C::ADDRESS_NONE;
// The I2C address of the Accelerometer (if found)
ScanI2C::DeviceAddress accelerometer_found = ScanI2C::ADDRESS_NONE;
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
ATECCX08A atecc;
@@ -163,6 +169,7 @@ static OSThread *powerFSMthread;
static OSThread *buttonThread;
uint32_t ButtonThread::longPressTime = 0;
#endif
static OSThread *accelerometerThread;
RadioInterface *rIf = NULL;
@@ -350,6 +357,15 @@ void setup()
* nodeTelemetrySensorsMap singleton. This wraps that logic in a temporary scope to declare the temporary field
* "found".
*/
#if !defined(ARCH_PORTDUINO)
auto acc_info = i2cScanner->firstAccelerometer();
accelerometer_found = acc_info.type != ScanI2C::DeviceType::NONE ? acc_info.address : accelerometer_found;
LOG_DEBUG("acc_info = %i\n", acc_info.type);
if (acc_info.type != ScanI2C::DeviceType::NONE) {
accelerometerThread = new AccelerometerThread(acc_info.type);
}
#endif
#define STRING(S) #S
@@ -459,14 +475,14 @@ void setup()
// Now that the mesh service is created, create any modules
setupModules();
// Do this after service.init (because that clears error_code)
// Do this after service.init (because that clears error_code)
#ifdef HAS_PMU
if (!pmu_found)
RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_NO_AXP192); // Record a hardware fault for missing hardware
#endif
// Don't call screen setup until after nodedb is setup (because we need
// the current region name)
// Don't call screen setup until after nodedb is setup (because we need
// the current region name)
#if defined(ST7735_CS) || defined(USE_EINK) || defined(ILI9341_DRIVER)
screen->setup();
#else

View File

@@ -24,6 +24,7 @@ extern ScanI2C::DeviceAddress screen_found;
extern ScanI2C::DeviceAddress cardkb_found;
extern uint8_t kb_model;
extern ScanI2C::DeviceAddress rtc_found;
extern ScanI2C::DeviceAddress accelerometer_found;
extern bool eink_found;
extern bool pmu_found;

View File

@@ -82,7 +82,7 @@ int MeshService::handleFromRadio(const meshtastic_MeshPacket *mp)
}
printPacket("Forwarding to phone", mp);
sendToPhone((meshtastic_MeshPacket *)mp);
sendToPhone(packetPool.allocCopy(*mp));
return 0;
}
@@ -231,7 +231,7 @@ void MeshService::sendToMesh(meshtastic_MeshPacket *p, RxSource src, bool ccToPh
}
if (ccToPhone) {
sendToPhone(p);
sendToPhone(packetPool.allocCopy(*p));
}
}
@@ -262,9 +262,8 @@ void MeshService::sendToPhone(meshtastic_MeshPacket *p)
releaseToPool(d);
}
meshtastic_MeshPacket *copied = packetPool.allocCopy(*p);
perhapsDecode(copied);
assert(toPhoneQueue.enqueue(copied, 0));
perhapsDecode(p);
assert(toPhoneQueue.enqueue(p, 0));
fromNum++;
}

View File

@@ -58,12 +58,6 @@ meshtastic_User &owner = devicestate.owner;
static uint8_t ourMacAddr[6];
/**
* The node number the user is currently looking at
* 0 if none
*/
NodeNum displayedNodeNum;
NodeDB::NodeDB() : nodes(devicestate.node_db), numNodes(&devicestate.node_db_count) {}
/**
@@ -171,6 +165,8 @@ void NodeDB::installDefaultConfig()
config.lora.hop_limit = HOP_RELIABLE;
config.position.gps_enabled = true;
config.position.position_broadcast_smart_enabled = true;
config.position.broadcast_smart_minimum_distance = 100;
config.position.broadcast_smart_minimum_interval_secs = 30;
if (config.device.role != meshtastic_Config_DeviceConfig_Role_ROUTER)
config.device.node_info_broadcast_secs = 3 * 60 * 60;
config.device.serial_enabled = true;
@@ -237,9 +233,7 @@ void NodeDB::installRoleDefaults(meshtastic_Config_DeviceConfig_Role role)
} else if (role == meshtastic_Config_DeviceConfig_Role_REPEATER) {
config.display.screen_on_secs = 1;
} else if (role == meshtastic_Config_DeviceConfig_Role_TRACKER) {
config.position.position_broadcast_smart_enabled = false;
config.position.position_broadcast_secs = 120;
config.position.gps_update_interval = 60;
config.position.gps_update_interval = 30;
} else if (role == meshtastic_Config_DeviceConfig_Role_SENSOR) {
moduleConfig.telemetry.environment_measurement_enabled = true;
moduleConfig.telemetry.environment_update_interval = 300;

View File

@@ -153,12 +153,6 @@ class NodeDB
void installDefaultDeviceState(), installDefaultChannels(), installDefaultConfig(), installDefaultModuleConfig();
};
/**
* The node number the user is currently looking at
* 0 if none
*/
extern NodeNum displayedNodeNum;
extern NodeDB nodeDB;
/*

View File

@@ -15,7 +15,7 @@ RF95Interface::RF95Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOL
SPIClass &spi)
: RadioLibInterface(cs, irq, rst, busy, spi)
{
// FIXME - we assume devices never get destroyed
LOG_WARN("RF95Interface(cs=%d, irq=%d, rst=%d, busy=%d)\n", cs, irq, rst, busy);
}
/** Some boards require GPIO control of tx vs rx paths */

View File

@@ -454,6 +454,7 @@ void RadioInterface::applyModemConfig()
// If user has manually specified a channel num, then use that, otherwise generate one by hashing the name
const char *channelName = channels.getName(channels.getPrimaryIndex());
// channel_num is actually (channel_num - 1), since modulus (%) returns values from 0 to (numChannels - 1)
int channel_num = (loraConfig.channel_num ? loraConfig.channel_num - 1 : hash(channelName)) % numChannels;
// Old frequency selection formula
@@ -480,7 +481,7 @@ void RadioInterface::applyModemConfig()
LOG_INFO("Radio myRegion->freqStart -> myRegion->freqEnd: %f -> %f (%f mhz)\n", myRegion->freqStart, myRegion->freqEnd,
myRegion->freqEnd - myRegion->freqStart);
LOG_INFO("Radio myRegion->numChannels: %d x %.3fkHz\n", numChannels, bw);
LOG_INFO("Radio channel_num: %d\n", channel_num);
LOG_INFO("Radio channel_num: %d\n", channel_num + 1);
LOG_INFO("Radio frequency: %f\n", getFreq());
LOG_INFO("Slot time: %u msec\n", slotTimeMsec);
}

View File

@@ -164,13 +164,13 @@ bool ReliableRouter::stopRetransmission(GlobalPacketId key)
{
auto old = findPendingPacket(key);
if (old) {
auto p = old->packet;
auto numErased = pending.erase(key);
assert(numErased == 1);
// remove the 'original' (identified by originator and packet->id) from the txqueue and free it
cancelSending(getFrom(old->packet), old->packet->id);
// now free the pooled copy for retransmission too. tryfix for #2228
if (old->packet)
packetPool.release(old->packet);
cancelSending(getFrom(p), p->id);
// now free the pooled copy for retransmission too
packetPool.release(p);
return true;
} else
return false;

View File

@@ -6,4 +6,13 @@ SX1268Interface::SX1268Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RA
SPIClass &spi)
: SX126xInterface(cs, irq, rst, busy, spi)
{
}
float SX1268Interface::getFreq()
{
// Set frequency to default of EU_433 if outside of allowed range (e.g. when region is UNSET)
if (savedFreq < 410 || savedFreq > 810)
return 433.125f;
else
return savedFreq;
}

View File

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

View File

@@ -47,6 +47,8 @@ template <typename T> bool SX126xInterface<T>::init()
int res = lora.begin(getFreq(), bw, sf, cr, syncWord, power, preambleLength, tcxoVoltage, useRegulatorLDO);
// \todo Display actual typename of the adapter, not just `SX126x`
LOG_INFO("SX126x init result %d\n", res);
if (res == RADIOLIB_ERR_CHIP_NOT_FOUND)
return false;
LOG_INFO("Frequency set to %f\n", getFreq());
LOG_INFO("Bandwidth set to %f\n", bw);

View File

@@ -13,6 +13,7 @@ SX128xInterface<T>::SX128xInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq,
SPIClass &spi)
: RadioLibInterface(cs, irq, rst, busy, spi, &lora), lora(&module)
{
LOG_WARN("SX128xInterface(cs=%d, irq=%d, rst=%d, busy=%d)\n", cs, irq, rst, busy);
}
/// Initialise the Driver transport hardware and software.
@@ -73,6 +74,12 @@ template <typename T> bool SX128xInterface<T>::init()
LOG_INFO("Bandwidth set to %f\n", bw);
LOG_INFO("Power output set to %d\n", power);
#if defined(SX128X_TXEN) && (SX128X_TXEN != RADIOLIB_NC) && defined(SX128X_RXEN) && (SX128X_RXEN != RADIOLIB_NC)
if (res == RADIOLIB_ERR_NONE) {
lora.setRfSwitchPins(SX128X_RXEN, SX128X_TXEN);
}
#endif
if (res == RADIOLIB_ERR_NONE)
res = lora.setCRC(2);

View File

@@ -262,6 +262,10 @@ typedef struct _meshtastic_Config_PositionConfig {
uint32_t rx_gpio;
/* (Re)define GPS_TX_PIN for your board. */
uint32_t tx_gpio;
/* The minimum distance in meters traveled (since the last send) before we can send a position to the mesh if position_broadcast_smart_enabled */
uint32_t broadcast_smart_minimum_distance;
/* The minumum 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;
} meshtastic_Config_PositionConfig;
/* Power Config\
@@ -360,6 +364,8 @@ typedef struct _meshtastic_Config_DisplayConfig {
meshtastic_Config_DisplayConfig_DisplayMode displaymode;
/* Print first line in pseudo-bold? FALSE is original style, TRUE is bold */
bool heading_bold;
/* Should we wake the screen up on accelerometer detected motion or tap */
bool wake_on_tap_or_motion;
} meshtastic_Config_DisplayConfig;
/* Lora Config */
@@ -522,20 +528,20 @@ 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}
#define meshtastic_Config_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_Config_PositionConfig_init_default {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}
#define meshtastic_Config_DisplayConfig_init_default {0, _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0}
#define meshtastic_Config_DisplayConfig_init_default {0, _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0, 0}
#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}
#define meshtastic_Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_Config_PositionConfig_init_zero {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}
#define meshtastic_Config_DisplayConfig_init_zero {0, _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0}
#define meshtastic_Config_DisplayConfig_init_zero {0, _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0, 0}
#define meshtastic_Config_LoRaConfig_init_zero {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_zero {0, _meshtastic_Config_BluetoothConfig_PairingMode_MIN, 0}
@@ -556,6 +562,8 @@ extern "C" {
#define meshtastic_Config_PositionConfig_position_flags_tag 7
#define meshtastic_Config_PositionConfig_rx_gpio_tag 8
#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_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
@@ -585,6 +593,7 @@ extern "C" {
#define meshtastic_Config_DisplayConfig_oled_tag 7
#define meshtastic_Config_DisplayConfig_displaymode_tag 8
#define meshtastic_Config_DisplayConfig_heading_bold_tag 9
#define meshtastic_Config_DisplayConfig_wake_on_tap_or_motion_tag 10
#define meshtastic_Config_LoRaConfig_use_preset_tag 1
#define meshtastic_Config_LoRaConfig_modem_preset_tag 2
#define meshtastic_Config_LoRaConfig_bandwidth_tag 3
@@ -650,7 +659,9 @@ X(a, STATIC, SINGULAR, UINT32, gps_update_interval, 5) \
X(a, STATIC, SINGULAR, UINT32, gps_attempt_time, 6) \
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, tx_gpio, 9) \
X(a, STATIC, SINGULAR, UINT32, broadcast_smart_minimum_distance, 10) \
X(a, STATIC, SINGULAR, UINT32, broadcast_smart_minimum_interval_secs, 11)
#define meshtastic_Config_PositionConfig_CALLBACK NULL
#define meshtastic_Config_PositionConfig_DEFAULT NULL
@@ -696,7 +707,8 @@ X(a, STATIC, SINGULAR, BOOL, flip_screen, 5) \
X(a, STATIC, SINGULAR, UENUM, units, 6) \
X(a, STATIC, SINGULAR, UENUM, oled, 7) \
X(a, STATIC, SINGULAR, UENUM, displaymode, 8) \
X(a, STATIC, SINGULAR, BOOL, heading_bold, 9)
X(a, STATIC, SINGULAR, BOOL, heading_bold, 9) \
X(a, STATIC, SINGULAR, BOOL, wake_on_tap_or_motion, 10)
#define meshtastic_Config_DisplayConfig_CALLBACK NULL
#define meshtastic_Config_DisplayConfig_DEFAULT NULL
@@ -750,11 +762,11 @@ 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 26
#define meshtastic_Config_DisplayConfig_size 26
#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 42
#define meshtastic_Config_PositionConfig_size 54
#define meshtastic_Config_PowerConfig_size 43
#define meshtastic_Config_size 198

View File

@@ -187,8 +187,8 @@ extern const pb_msgdesc_t meshtastic_OEMStore_msg;
/* Maximum encoded size of messages (where known) */
#define meshtastic_ChannelFile_size 638
#define meshtastic_DeviceState_size 21800
#define meshtastic_OEMStore_size 3006
#define meshtastic_DeviceState_size 22040
#define meshtastic_OEMStore_size 3020
#ifdef __cplusplus
} /* extern "C" */

View File

@@ -156,7 +156,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 440
#define meshtastic_LocalConfig_size 454
#define meshtastic_LocalModuleConfig_size 420
#ifdef __cplusplus

View File

@@ -563,6 +563,8 @@ typedef struct _meshtastic_NodeInfo {
/* The latest device metrics for the node. */
bool has_device_metrics;
meshtastic_DeviceMetrics device_metrics;
/* local channel index we heard that node on. Only populated if its not the default channel. */
uint8_t channel;
} meshtastic_NodeInfo;
/* Unique local debugging info for this node
@@ -823,7 +825,7 @@ extern "C" {
#define meshtastic_Data_init_default {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0}
#define meshtastic_Waypoint_init_default {0, 0, 0, 0, 0, "", "", 0}
#define meshtastic_MeshPacket_init_default {0, 0, 0, 0, {meshtastic_Data_init_default}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN}
#define meshtastic_NodeInfo_init_default {0, false, meshtastic_User_init_default, false, meshtastic_Position_init_default, 0, 0, false, meshtastic_DeviceMetrics_init_default}
#define meshtastic_NodeInfo_init_default {0, false, meshtastic_User_init_default, false, meshtastic_Position_init_default, 0, 0, false, meshtastic_DeviceMetrics_init_default, 0}
#define meshtastic_MyNodeInfo_init_default {0, 0, 0, "", _meshtastic_CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0}
#define meshtastic_LogRecord_init_default {"", 0, "", _meshtastic_LogRecord_Level_MIN}
#define meshtastic_QueueStatus_init_default {0, 0, 0, 0}
@@ -838,7 +840,7 @@ extern "C" {
#define meshtastic_Data_init_zero {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0}
#define meshtastic_Waypoint_init_zero {0, 0, 0, 0, 0, "", "", 0}
#define meshtastic_MeshPacket_init_zero {0, 0, 0, 0, {meshtastic_Data_init_zero}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN}
#define meshtastic_NodeInfo_init_zero {0, false, meshtastic_User_init_zero, false, meshtastic_Position_init_zero, 0, 0, false, meshtastic_DeviceMetrics_init_zero}
#define meshtastic_NodeInfo_init_zero {0, false, meshtastic_User_init_zero, false, meshtastic_Position_init_zero, 0, 0, false, meshtastic_DeviceMetrics_init_zero, 0}
#define meshtastic_MyNodeInfo_init_zero {0, 0, 0, "", _meshtastic_CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0}
#define meshtastic_LogRecord_init_zero {"", 0, "", _meshtastic_LogRecord_Level_MIN}
#define meshtastic_QueueStatus_init_zero {0, 0, 0, 0}
@@ -915,6 +917,7 @@ extern "C" {
#define meshtastic_NodeInfo_snr_tag 4
#define meshtastic_NodeInfo_last_heard_tag 5
#define meshtastic_NodeInfo_device_metrics_tag 6
#define meshtastic_NodeInfo_channel_tag 7
#define meshtastic_MyNodeInfo_my_node_num_tag 1
#define meshtastic_MyNodeInfo_has_gps_tag 2
#define meshtastic_MyNodeInfo_max_channels_tag 3
@@ -1067,7 +1070,8 @@ X(a, STATIC, OPTIONAL, MESSAGE, user, 2) \
X(a, STATIC, OPTIONAL, MESSAGE, position, 3) \
X(a, STATIC, SINGULAR, FLOAT, snr, 4) \
X(a, STATIC, SINGULAR, FIXED32, last_heard, 5) \
X(a, STATIC, OPTIONAL, MESSAGE, device_metrics, 6)
X(a, STATIC, OPTIONAL, MESSAGE, device_metrics, 6) \
X(a, STATIC, SINGULAR, UINT32, channel, 7)
#define meshtastic_NodeInfo_CALLBACK NULL
#define meshtastic_NodeInfo_DEFAULT NULL
#define meshtastic_NodeInfo_user_MSGTYPE meshtastic_User
@@ -1207,7 +1211,7 @@ extern const pb_msgdesc_t meshtastic_DeviceMetadata_msg;
#define meshtastic_LogRecord_size 81
#define meshtastic_MeshPacket_size 321
#define meshtastic_MyNodeInfo_size 179
#define meshtastic_NodeInfo_size 258
#define meshtastic_NodeInfo_size 261
#define meshtastic_Position_size 137
#define meshtastic_QueueStatus_size 23
#define meshtastic_RouteDiscovery_size 40

View File

@@ -645,7 +645,7 @@ void handleReport(HTTPRequest *req, HTTPResponse *res)
// data->radio
JSONObject jsonObjRadio;
jsonObjRadio["frequency"] = new JSONValue(RadioLibInterface::instance->getFreq());
jsonObjRadio["lora_channel"] = new JSONValue((int)RadioLibInterface::instance->getChannelNum());
jsonObjRadio["lora_channel"] = new JSONValue((int)RadioLibInterface::instance->getChannelNum() + 1);
// collect data to inner data object
JSONObject jsonObjInner;
@@ -833,7 +833,7 @@ void handleScanNetworks(HTTPRequest *req, HTTPResponse *res)
if (WiFi.encryptionType(i) != WIFI_AUTH_OPEN) {
JSONObject thisNetwork;
thisNetwork["ssid"] = new JSONValue(ssidArray);
thisNetwork["rssi"] = new JSONValue(WiFi.RSSI(i));
thisNetwork["rssi"] = new JSONValue(int(WiFi.RSSI(i)));
networkObjs.push_back(new JSONValue(thisNetwork));
}
// Yield some cpu cycles to IP stack.

View File

@@ -446,8 +446,6 @@ int CannedMessageModule::getPrevIndex()
void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
displayedNodeNum = 0; // Not currently showing a node pane
char buffer[50];
if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE) {

View File

@@ -72,7 +72,8 @@ void setupModules()
new AirQualityTelemetryModule();
}
#endif
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(TTGO_T_ECHO) && !defined(CONFIG_IDF_TARGET_ESP32S2)
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(TTGO_T_ECHO) && !defined(CONFIG_IDF_TARGET_ESP32S2) && \
!defined(CONFIG_IDF_TARGET_ESP32C3)
new SerialModule();
#endif
#ifdef ARCH_ESP32

View File

@@ -144,10 +144,10 @@ int32_t PositionModule::runOnce()
// We limit our GPS broadcasts to a max rate
uint32_t now = millis();
uint32_t intervalMs = config.position.position_broadcast_secs > 0 ? config.position.position_broadcast_secs * 1000
: default_broadcast_interval_secs * 1000;
if (lastGpsSend == 0 || (now - lastGpsSend) >= intervalMs) {
uint32_t intervalMs = getConfiguredOrDefaultMs(config.position.position_broadcast_secs, default_broadcast_interval_secs);
uint32_t msSinceLastSend = now - lastGpsSend;
if (lastGpsSend == 0 || msSinceLastSend >= intervalMs) {
// Only send packets if the channel is less than 40% utilized.
if (airTime->isTxAllowedChannelUtil()) {
if (node->has_position && (node->position.latitude_i != 0 || node->position.longitude_i != 0)) {
@@ -165,39 +165,32 @@ int32_t PositionModule::runOnce()
}
}
} else if (config.position.position_broadcast_smart_enabled) {
// Only send packets if the channel is less than 25% utilized.
if (airTime->isTxAllowedChannelUtil(true)) {
// 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)) {
meshtastic_NodeInfo *node2 = service.refreshMyNodeInfo(); // should guarantee there is now a position
if (node2->has_position && (node2->position.latitude_i != 0 || node2->position.longitude_i != 0)) {
// The minimum distance to travel before we are able to send a new position packet.
const uint32_t distanceTravelMinimum = 30;
const uint32_t distanceTravelThreshold =
config.position.broadcast_smart_minimum_distance > 0 ? config.position.broadcast_smart_minimum_distance : 100;
// The minimum time that would pass before we are able to send a new position packet.
const uint32_t timeTravelMinimum = 30;
// 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 distance = GeoCoord::latLongToMeter(lastGpsLatitude * 1e-7, lastGpsLongitude * 1e-7,
node->position.latitude_i * 1e-7, node->position.longitude_i * 1e-7);
float distanceTraveledSinceLastSend =
GeoCoord::latLongToMeter(lastGpsLatitude * 1e-7, lastGpsLongitude * 1e-7, node->position.latitude_i * 1e-7,
node->position.longitude_i * 1e-7);
// Yes, this has a bunch of magic numbers. Sorry. This is to make the scale non-linear.
const float distanceTravelMath = 1203 / (sqrt(pow(myNodeInfo.bitrate, 1.5) / 1.1));
uint32_t distanceTravelThreshold =
(distanceTravelMath >= distanceTravelMinimum) ? distanceTravelMath : distanceTravelMinimum;
// Yes, this has a bunch of magic numbers. Sorry.
uint32_t timeTravel =
((1500 / myNodeInfo.bitrate) >= timeTravelMinimum) ? (1500 / myNodeInfo.bitrate) : timeTravelMinimum;
// If the distance traveled since the last update is greater than distanceTravelMinimum meters
// and it's been at least timeTravelMinimum seconds since the last update
if ((abs(distance) >= distanceTravelThreshold) && (now - lastGpsSend) >= (timeTravel * 1000)) {
if ((abs(distanceTraveledSinceLastSend) >= distanceTravelThreshold) && msSinceLastSend >= minimumTimeThreshold) {
bool requestReplies = currentGeneration != radioGeneration;
currentGeneration = radioGeneration;
LOG_INFO("Sending smart pos@%x:6 to mesh (wantReplies=%d, d=%d, dtt=%d, tt=%d)\n", node2->position.timestamp,
requestReplies, distance, distanceTravelThreshold, timeTravel);
LOG_INFO("Sending smart pos@%x:6 to mesh (distanceTraveled=%fm, minDistanceThreshold=%im, timeElapsed=%ims, "
"minTimeInterval=%ims)\n",
node2->position.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

View File

@@ -44,7 +44,8 @@
*/
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(TTGO_T_ECHO) && !defined(CONFIG_IDF_TARGET_ESP32S2)
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(TTGO_T_ECHO) && !defined(CONFIG_IDF_TARGET_ESP32S2) && \
!defined(CONFIG_IDF_TARGET_ESP32C3)
#define RX_BUFFER 128
#define TIMEOUT 250

View File

@@ -8,7 +8,8 @@
#include <Arduino.h>
#include <functional>
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(TTGO_T_ECHO) && !defined(CONFIG_IDF_TARGET_ESP32S2)
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(TTGO_T_ECHO) && !defined(CONFIG_IDF_TARGET_ESP32S2) && \
!defined(CONFIG_IDF_TARGET_ESP32C3)
class SerialModule : public StreamAPI, private concurrency::OSThread
{

View File

@@ -153,8 +153,6 @@ AudioModule::AudioModule() : SinglePortModule("AudioModule", meshtastic_PortNum_
void AudioModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
displayedNodeNum = 0; // Not currently showing a node pane
char buffer[50];
display->setTextAlignment(TEXT_ALIGN_LEFT);

View File

@@ -85,7 +85,6 @@ void esp32Setup()
{
uint32_t seed = esp_random();
LOG_DEBUG("Setting random seed %u\n", seed);
randomSeed(seed); // ESP docs say this is fairly random
LOG_DEBUG("Total heap: %d\n", ESP.getHeapSize());
LOG_DEBUG("Free heap: %d\n", ESP.getFreeHeap());
@@ -178,6 +177,7 @@ void cpuDeepSleep(uint64_t msecToWake)
Note: we don't isolate pins that are used for the LORA, LED, i2c, spi or the wake button
*/
#if SOC_RTCIO_HOLD_SUPPORTED
static const uint8_t rtcGpios[] = {/* 0, */ 2,
/* 4, */
#ifndef USE_JTAG
@@ -191,6 +191,7 @@ void cpuDeepSleep(uint64_t msecToWake)
for (int i = 0; i < sizeof(rtcGpios); i++)
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.
@@ -200,7 +201,9 @@ void cpuDeepSleep(uint64_t msecToWake)
#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.
#if SOC_RTCIO_HOLD_SUPPORTED
uint64_t gpioMask = (1ULL << BUTTON_PIN);
#endif
#ifdef BUTTON_NEED_PULLUP
gpio_pullup_en((gpio_num_t)BUTTON_PIN);
@@ -210,9 +213,11 @@ void cpuDeepSleep(uint64_t msecToWake)
// FIXME change polarity in hw so we can wake on ANY_HIGH instead - that would allow us to use all three buttons (instead of
// just the first) gpio_pullup_en((gpio_num_t)BUTTON_PIN);
#if SOC_PM_SUPPORT_EXT_WAKEUP
esp_sleep_enable_ext1_wakeup(gpioMask, ESP_EXT1_WAKEUP_ALL_LOW);
#endif
#endif
esp_sleep_enable_timer_wakeup(msecToWake * 1000ULL); // call expects usecs
esp_deep_sleep_start(); // TBD mA sleep current (battery)
}
}

View File

@@ -61,13 +61,15 @@ void setCPUFast(bool on)
* all WiFi use cases.
* (Added: Dec 23, 2021 by Jm Casler)
*/
#ifndef CONFIG_IDF_TARGET_ESP32C3
LOG_DEBUG("Setting CPU to 240mhz because WiFi is in use.\n");
setCpuFrequencyMhz(240);
#endif
return;
}
// The Heltec LORA32 V1 runs at 26 MHz base frequency and doesn't react well to switching to 80 MHz...
#ifndef ARDUINO_HELTEC_WIFI_LORA_32
#if !defined(ARDUINO_HELTEC_WIFI_LORA_32) && !defined(CONFIG_IDF_TARGET_ESP32C3)
setCpuFrequencyMhz(on ? 240 : 80);
#endif
@@ -97,10 +99,15 @@ void setGPSPower(bool on)
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);
#elif (HW_VENDOR == meshtastic_HardwareModel_LILYGO_TBEAM_S3_CORE)
// t-beam-s3-core GNSS power channel
on ? PMU->enablePowerOutput(XPOWERS_ALDO4) : PMU->disablePowerOutput(XPOWERS_ALDO4);
#endif
} else if (model == XPOWERS_AXP192) {
// t-beam GNSS power channel
// t-beam v1.1 GNSS power channel
on ? PMU->enablePowerOutput(XPOWERS_LDO3) : PMU->disablePowerOutput(XPOWERS_LDO3);
}
}
@@ -235,8 +242,14 @@ void doDeepSleep(uint64_t msecToWake)
uint8_t model = PMU->getChipModel();
if (model == XPOWERS_AXP2101) {
#if (HW_VENDOR == meshtastic_HardwareModel_TBEAM)
// t-beam v1.2 radio power channel
PMU->disablePowerOutput(XPOWERS_ALDO2); // lora radio power channel
#elif (HW_VENDOR == meshtastic_HardwareModel_LILYGO_TBEAM_S3_CORE)
PMU->disablePowerOutput(XPOWERS_ALDO3); // lora radio power channel
#endif
} else if (model == XPOWERS_AXP192) {
// t-beam v1.1 radio power channel
PMU->disablePowerOutput(XPOWERS_LDO2); // lora radio power channel
}
}
@@ -337,6 +350,8 @@ void enableModemSleep()
esp32_config.max_freq_mhz = CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ;
#elif CONFIG_IDF_TARGET_ESP32S2
esp32_config.max_freq_mhz = CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ;
#elif CONFIG_IDF_TARGET_ESP32C3
esp32_config.max_freq_mhz = CONFIG_ESP32C3_DEFAULT_CPU_FREQ_MHZ;
#else
esp32_config.max_freq_mhz = CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ;
#endif

View File

@@ -0,0 +1,8 @@
[env:ai-c3]
extends = esp32c3_base
board = esp32-c3-devkitm-1
board_level = extra
build_flags =
${esp32_base.build_flags}
-D PRIVATE_HW
-I variants/ai-c3

26
variants/ai-c3/variant.h Normal file
View File

@@ -0,0 +1,26 @@
// #define BUTTON_NEED_PULLUP // if set we need to turn on the internal CPU pullup during sleep
#define I2C_SDA 8
#define I2C_SCL 9
#define BUTTON_PIN 0
#define USE_RF95
#undef RF95_SCK
#define RF95_SCK 4
#undef RF95_MISO
#define RF95_MISO 5
#undef RF95_MOSI
#define RF95_MOSI 6
#undef RF95_NSS
#define RF95_NSS 7
#define LORA_DIO0 10 // a No connect on the SX1262 module
#define LORA_DIO1 3 // a No connect on the SX1262 module
#define LORA_RESET 2
#undef GPS_RX_PIN
#undef GPS_TX_PIN
#define HAS_SCREEN 0
#define HAS_GPS 0

View File

@@ -59,4 +59,5 @@
#define SX128X_RESET LORA_RESET
#define SX128X_RXEN 21
#define SX128X_TXEN 10
#define SX128X_MAX_POWER 3
#endif

View File

@@ -1,4 +1,4 @@
[VERSION]
major = 2
minor = 1
build = 2
build = 5