mirror of
https://github.com/meshtastic/firmware.git
synced 2025-12-29 06:00:33 +00:00
Compare commits
23 Commits
v2.2.19.8f
...
v2.2.21.7f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7f7c5cbd62 | ||
|
|
0c0a3c4b55 | ||
|
|
bf762bc58d | ||
|
|
84e578323e | ||
|
|
bdbe42dfd0 | ||
|
|
4f64c4f7b9 | ||
|
|
af5ac32048 | ||
|
|
9586c68c65 | ||
|
|
ca45888f3e | ||
|
|
1e4ecea6fc | ||
|
|
d1ea589757 | ||
|
|
af52dcecdf | ||
|
|
0ae4622393 | ||
|
|
a49740cd56 | ||
|
|
417feee47f | ||
|
|
d604a76c73 | ||
|
|
ac9c5f81b9 | ||
|
|
d6fa190025 | ||
|
|
f2c04c5504 | ||
|
|
4ae5443c3b | ||
|
|
6b5101ec67 | ||
|
|
062c646814 | ||
|
|
bccc0d47eb |
4
.github/workflows/main_matrix.yml
vendored
4
.github/workflows/main_matrix.yml
vendored
@@ -64,6 +64,7 @@ jobs:
|
||||
- board: tlora-v1
|
||||
- board: tlora_v1_3
|
||||
- board: tlora-v2-1-1_6
|
||||
- board: tlora-v2-1-1_6-tcxo
|
||||
- board: tlora-v2-1-1_8
|
||||
- board: tbeam
|
||||
- board: heltec-ht62-esp32c3-sx1262
|
||||
@@ -79,6 +80,7 @@ jobs:
|
||||
- board: m5stack-core
|
||||
- board: m5stack-coreink
|
||||
- board: nano-g1-explorer
|
||||
- board: chatter2
|
||||
uses: ./.github/workflows/build_esp32.yml
|
||||
with:
|
||||
board: ${{ matrix.board }}
|
||||
@@ -245,7 +247,7 @@ jobs:
|
||||
id: version
|
||||
|
||||
- name: Move files up
|
||||
run: mv -b -t ./ ./*tbeam-2*/littlefs*.bin ./*tbeam-2*/bleota.bin ./*tbeam-s3*/bleota-s3.bin ./**/firmware*.bin ./*t-echo*/Meshtastic_nRF52_factory_erase.uf2 ./**/firmware-*.uf2 ./**/firmware-*-ota.zip ./**/*.elf ./*native*/*device-*.sh ./*native*/*device-*.bat ./firmware-raspbian-*/release/meshtasticd_linux_aarch64 ./firmware-raspbian-*/bin/config-dist.yaml
|
||||
run: mv -b -t ./ ./*tbeam-2*/littlefs*.bin ./*tbeam-2*/bleota.bin ./*tbeam-s3*/bleota-s3.bin ./**/firmware*.bin ./*t-echo*/Meshtastic_nRF52_factory_erase_v2.uf2 ./**/firmware-*.uf2 ./**/firmware-*-ota.zip ./**/*.elf ./*native*/*device-*.sh ./*native*/*device-*.bat ./firmware-raspbian-*/release/meshtasticd_linux_aarch64 ./firmware-raspbian-*/bin/config-dist.yaml
|
||||
|
||||
- name: Repackage in single firmware zip
|
||||
uses: actions/upload-artifact@v3
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
; The Portduino based sim environment on top of any host OS, all hardware will be simulated
|
||||
[portduino_base]
|
||||
platform = https://github.com/meshtastic/platform-native.git#04435d06e39916a6c019d511518d8e95c659dfbd
|
||||
platform = https://github.com/meshtastic/platform-native.git#a28dd5a9ccd5c48a9bede46037855ff83915d74b
|
||||
framework = arduino
|
||||
|
||||
build_src_filter =
|
||||
|
||||
Binary file not shown.
BIN
bin/Meshtastic_nRF52_factory_erase_v2.uf2
Normal file
BIN
bin/Meshtastic_nRF52_factory_erase_v2.uf2
Normal file
Binary file not shown.
@@ -60,6 +60,11 @@ GPIO:
|
||||
GPS:
|
||||
# SerialPath: /dev/ttyS0
|
||||
|
||||
### Specify I2C device, or leave blank for none
|
||||
|
||||
I2C:
|
||||
# I2CDevice: /dev/i2c-1
|
||||
|
||||
### Set up SPI displays here. Note that I2C displays are generally auto-detected.
|
||||
|
||||
Display:
|
||||
@@ -95,3 +100,8 @@ Touchscreen:
|
||||
|
||||
Input:
|
||||
# KeyboardDevice: /dev/input/event0
|
||||
|
||||
###
|
||||
|
||||
Logging:
|
||||
LogLevel: info # debug, info, warn, error
|
||||
|
||||
@@ -10,10 +10,12 @@ default_envs = tbeam
|
||||
;default_envs = heltec-v2_0
|
||||
;default_envs = heltec-v2_1
|
||||
;default_envs = heltec-wireless-tracker
|
||||
;default_envs = chatter2
|
||||
;default_envs = tlora-v1
|
||||
;default_envs = tlora_v1_3
|
||||
;default_envs = tlora-v2
|
||||
;default_envs = tlora-v2-1-1_6
|
||||
;default_envs = tlora-v2-1-1_6-tcxo
|
||||
;default_envs = tlora-t3s3-v1
|
||||
;default_envs = lora-relay-v1 # nrf board
|
||||
;default_envs = t-echo
|
||||
@@ -73,7 +75,7 @@ lib_deps =
|
||||
https://github.com/meshtastic/esp8266-oled-ssd1306.git#ee628ee6c9588d4c56c9e3da35f0fc9448ad54a8 ; ESP8266_SSD1306
|
||||
mathertel/OneButton@^2.5.0 ; OneButton library for non-blocking button debounce
|
||||
https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159
|
||||
https://github.com/meshtastic/TinyGPSPlus.git#076e8d2c8fb702d9be5b08c55b93ff76f8af7e61
|
||||
https://github.com/meshtastic/TinyGPSPlus.git#2044b2c51e91ab4cd8cc93b15e40658cd808dd06
|
||||
https://github.com/meshtastic/ArduinoThread.git#72921ac222eed6f526ba1682023cee290d9aa1b3
|
||||
nanopb/Nanopb@^0.4.7
|
||||
erriez/ErriezCRC32@^1.0.1
|
||||
|
||||
Submodule protobufs updated: 44e369e181...b508d2e7ce
@@ -193,15 +193,7 @@ class ButtonThread : public concurrency::OSThread
|
||||
static void userButtonMultiPressed()
|
||||
{
|
||||
if (!config.device.disable_triple_click && (gps != nullptr)) {
|
||||
config.position.gps_enabled = !(config.position.gps_enabled);
|
||||
if (config.position.gps_enabled) {
|
||||
LOG_DEBUG("Flag set to true to restore power\n");
|
||||
gps->enable();
|
||||
|
||||
} else {
|
||||
LOG_DEBUG("Flag set to false for gps power\n");
|
||||
gps->disable();
|
||||
}
|
||||
gps->toggleGpsMode();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,12 +10,12 @@ template <class T> class Observable;
|
||||
*/
|
||||
template <class T> class Observer
|
||||
{
|
||||
std::list<Observable<T> *> observed;
|
||||
std::list<Observable<T> *> observables;
|
||||
|
||||
public:
|
||||
virtual ~Observer();
|
||||
|
||||
/// Stop watching the obserable
|
||||
/// Stop watching the observable
|
||||
void unobserve(Observable<T> *o);
|
||||
|
||||
/// Start watching a specified observable
|
||||
@@ -86,21 +86,21 @@ template <class T> class Observable
|
||||
|
||||
template <class T> Observer<T>::~Observer()
|
||||
{
|
||||
for (typename std::list<Observable<T> *>::const_iterator iterator = observed.begin(); iterator != observed.end();
|
||||
for (typename std::list<Observable<T> *>::const_iterator iterator = observables.begin(); iterator != observables.end();
|
||||
++iterator) {
|
||||
(*iterator)->removeObserver(this);
|
||||
}
|
||||
observed.clear();
|
||||
observables.clear();
|
||||
}
|
||||
|
||||
template <class T> void Observer<T>::unobserve(Observable<T> *o)
|
||||
{
|
||||
o->removeObserver(this);
|
||||
observed.remove(o);
|
||||
observables.remove(o);
|
||||
}
|
||||
|
||||
template <class T> void Observer<T>::observe(Observable<T> *o)
|
||||
{
|
||||
observed.push_back(o);
|
||||
observables.push_back(o);
|
||||
o->addObserver(this);
|
||||
}
|
||||
}
|
||||
104
src/Power.cpp
104
src/Power.cpp
@@ -164,7 +164,8 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
||||
#endif
|
||||
|
||||
#ifndef BATTERY_SENSE_SAMPLES
|
||||
#define BATTERY_SENSE_SAMPLES 30
|
||||
#define BATTERY_SENSE_SAMPLES \
|
||||
30 // Set the number of samples, it has an effect of increasing sensitivity in complex electromagnetic environment.
|
||||
#endif
|
||||
|
||||
#ifdef BATTERY_PIN
|
||||
@@ -176,66 +177,71 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
||||
if (millis() - last_read_time_ms > min_read_interval) {
|
||||
last_read_time_ms = millis();
|
||||
|
||||
// Set the number of samples, it has an effect of increasing sensitivity, especially in complex electromagnetic
|
||||
// environment.
|
||||
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++) {
|
||||
// ADC2 wifi bug workaround, see
|
||||
// https://github.com/espressif/arduino-esp32/issues/102
|
||||
WRITE_PERI_REG(SENS_SAR_READ_CTRL2_REG, RTC_reg_b);
|
||||
SET_PERI_REG_MASK(SENS_SAR_READ_CTRL2_REG, SENS_SAR2_DATA_INV);
|
||||
adc2_get_raw(adc_channel, ADC_WIDTH_BIT_12, &adc_buf);
|
||||
raw += adc_buf;
|
||||
}
|
||||
#endif // BAT_MEASURE_ADC_UNIT
|
||||
#else // !ARCH_ESP32
|
||||
float scaled = 0;
|
||||
|
||||
#ifdef ARCH_ESP32 // ADC block for espressif platforms
|
||||
raw = espAdcRead();
|
||||
scaled = esp_adc_cal_raw_to_voltage(raw, adc_characs);
|
||||
scaled *= operativeAdcMultiplier;
|
||||
#else // block for all other platforms
|
||||
for (uint32_t i = 0; i < BATTERY_SENSE_SAMPLES; i++) {
|
||||
raw += analogRead(BATTERY_PIN);
|
||||
}
|
||||
#endif
|
||||
raw = raw / BATTERY_SENSE_SAMPLES;
|
||||
float scaled;
|
||||
#ifdef ARCH_ESP32
|
||||
scaled = esp_adc_cal_raw_to_voltage(raw, adc_characs);
|
||||
scaled *= operativeAdcMultiplier;
|
||||
#else
|
||||
#ifndef VBAT_RAW_TO_SCALED
|
||||
scaled = 1000.0 * operativeAdcMultiplier * (AREF_VOLTAGE / 1024.0) * raw;
|
||||
#else
|
||||
scaled = VBAT_RAW_TO_SCALED(raw); // defined in variant.h
|
||||
#endif // VBAT RAW TO SCALED
|
||||
#endif // ARCH_ESP32
|
||||
// LOG_DEBUG("battery gpio %d raw val=%u scaled=%u\n", BATTERY_PIN, raw, (uint32_t)(scaled));
|
||||
|
||||
scaled = operativeAdcMultiplier * ((1000 * AREF_VOLTAGE) / pow(2, BATTERY_SENSE_RESOLUTION_BITS)) * raw;
|
||||
#endif
|
||||
// LOG_DEBUG("battery gpio %d raw val=%u scaled=%u\n", BATTERY_PIN, raw, (uint32_t)(scaled));
|
||||
last_read_value = scaled;
|
||||
return scaled;
|
||||
} else {
|
||||
return last_read_value;
|
||||
}
|
||||
#else
|
||||
return 0;
|
||||
#endif // BATTERY_PIN
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(ARCH_ESP32) && !defined(HAS_PMU) && defined(BATTERY_PIN)
|
||||
/**
|
||||
* ESP32 specific function for getting calibrated ADC reads
|
||||
*/
|
||||
uint32_t espAdcRead()
|
||||
{
|
||||
|
||||
uint32_t raw = 0;
|
||||
|
||||
#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++) {
|
||||
// ADC2 wifi bug workaround, see
|
||||
// https://github.com/espressif/arduino-esp32/issues/102
|
||||
WRITE_PERI_REG(SENS_SAR_READ_CTRL2_REG, RTC_reg_b);
|
||||
SET_PERI_REG_MASK(SENS_SAR_READ_CTRL2_REG, SENS_SAR2_DATA_INV);
|
||||
adc2_get_raw(adc_channel, ADC_WIDTH_BIT_12, &adc_buf);
|
||||
raw += adc_buf;
|
||||
}
|
||||
#endif // BAT_MEASURE_ADC_UNIT
|
||||
raw = raw / BATTERY_SENSE_SAMPLES;
|
||||
return raw;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* return true if there is a battery installed in this unit
|
||||
*/
|
||||
@@ -894,4 +900,4 @@ bool Power::axpChipInit()
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,10 @@
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifdef ARCH_PORTDUINO
|
||||
#include "platform/portduino/PortduinoGlue.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* A printer that doesn't go anywhere
|
||||
*/
|
||||
@@ -68,7 +72,15 @@ size_t RedirectablePrint::vprintf(const char *format, va_list arg)
|
||||
|
||||
size_t RedirectablePrint::log(const char *logLevel, const char *format, ...)
|
||||
{
|
||||
if (moduleConfig.serial.override_console_serial_port && strcmp(logLevel, "DEBUG") == 0) {
|
||||
#ifdef ARCH_PORTDUINO
|
||||
if (settingsMap[logoutputlevel] < level_debug && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_DEBUG) == 0)
|
||||
return 0;
|
||||
else if (settingsMap[logoutputlevel] < level_info && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_INFO) == 0)
|
||||
return 0;
|
||||
else if (settingsMap[logoutputlevel] < level_warn && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_WARN) == 0)
|
||||
return 0;
|
||||
#endif
|
||||
if (moduleConfig.serial.override_console_serial_port && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_DEBUG) == 0) {
|
||||
return 0;
|
||||
}
|
||||
size_t r = 0;
|
||||
|
||||
108
src/gps/GPS.cpp
108
src/gps/GPS.cpp
@@ -16,7 +16,7 @@
|
||||
#define GPS_RESET_MODE HIGH
|
||||
#endif
|
||||
|
||||
#if defined(NRF52840_XXAA) || defined(NRF52833_XXAA) || defined(ARCH_ESP32) || defined(aLinuxInputImpl)
|
||||
#if defined(NRF52840_XXAA) || defined(NRF52833_XXAA) || defined(ARCH_ESP32) || defined(ARCH_PORTDUINO)
|
||||
HardwareSerial *GPS::_serial_gps = &Serial1;
|
||||
#else
|
||||
HardwareSerial *GPS::_serial_gps = NULL;
|
||||
@@ -251,17 +251,9 @@ int GPS::getACK(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t
|
||||
bool GPS::setup()
|
||||
{
|
||||
int msglen = 0;
|
||||
bool isProblematicGPS = false;
|
||||
|
||||
if (!didSerialInit) {
|
||||
#if !defined(GPS_UC6580)
|
||||
#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 defined(RAK4630) && defined(PIN_3V3_EN)
|
||||
// If we are using the RAK4630 and we have no other peripherals on the I2C bus or module interest in 3V3_S,
|
||||
@@ -380,7 +372,7 @@ bool GPS::setup()
|
||||
LOG_WARN("Unable to set GPS update rate.\n");
|
||||
}
|
||||
|
||||
msglen = makeUBXPacket(0x06, 0x01, sizeof(_message_GGL), _message_GGL);
|
||||
msglen = makeUBXPacket(0x06, 0x01, sizeof(_message_GLL), _message_GLL);
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x01, 300) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to disable NMEA GGL.\n");
|
||||
@@ -416,6 +408,12 @@ bool GPS::setup()
|
||||
LOG_WARN("Unable to enable NMEA GGA.\n");
|
||||
}
|
||||
|
||||
msglen = makeUBXPacket(0x06, 0x01, sizeof(_message_AID), _message_AID);
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x01, 300) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to disable UBX-AID.\n");
|
||||
}
|
||||
|
||||
if (uBloxProtocolVersion >= 18) {
|
||||
msglen = makeUBXPacket(0x06, 0x86, sizeof(_message_PMS), _message_PMS);
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
@@ -423,36 +421,31 @@ bool GPS::setup()
|
||||
LOG_WARN("Unable to enable powersaving for GPS.\n");
|
||||
}
|
||||
} else {
|
||||
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");
|
||||
}
|
||||
if (strncmp(info.hwVersion, "00040007", 8) == 0) { // This PSM mode is only for Neo-6
|
||||
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 Neo-6.\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_PSM);
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x11, 300) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to enable powersaving mode for GPS.\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");
|
||||
}
|
||||
msglen = makeUBXPacket(0x06, 0x09, sizeof(_message_SAVE), _message_SAVE);
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x09, 2000) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to save GNSS module configuration.\n");
|
||||
} else {
|
||||
LOG_INFO("GNSS module configuration saved!\n");
|
||||
}
|
||||
}
|
||||
didSerialInit = true;
|
||||
@@ -611,7 +604,7 @@ uint32_t GPS::getSleepTime() const
|
||||
uint32_t t = config.position.gps_update_interval;
|
||||
|
||||
// We'll not need the GPS thread to wake up again after first acq. with fixed position.
|
||||
if (!config.position.gps_enabled || config.position.fixed_position)
|
||||
if (config.position.gps_mode != meshtastic_Config_PositionConfig_GpsMode_ENABLED || config.position.fixed_position)
|
||||
t = UINT32_MAX; // Sleep forever now
|
||||
|
||||
if (t == UINT32_MAX)
|
||||
@@ -632,21 +625,24 @@ void GPS::publishUpdate()
|
||||
// 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)
|
||||
if (config.position.gps_mode == meshtastic_Config_PositionConfig_GpsMode_ENABLED) {
|
||||
positionModule->handleNewPosition();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32_t GPS::runOnce()
|
||||
{
|
||||
if (!GPSInitFinished) {
|
||||
if (!_serial_gps)
|
||||
if (!_serial_gps || config.position.gps_mode == meshtastic_Config_PositionConfig_GpsMode_NOT_PRESENT) {
|
||||
LOG_INFO("GPS set to not-present. Skipping probe.\n");
|
||||
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) {
|
||||
if (config.position.gps_mode != meshtastic_Config_PositionConfig_GpsMode_ENABLED) {
|
||||
return disable();
|
||||
}
|
||||
// ONCE we will factory reset the GPS for bug #327
|
||||
@@ -669,7 +665,7 @@ int32_t GPS::runOnce()
|
||||
// if we have received valid NMEA claim we are connected
|
||||
setConnected();
|
||||
} else {
|
||||
if ((config.position.gps_enabled == 1) && (gnssModel == GNSS_MODEL_UBLOX)) {
|
||||
if ((config.position.gps_mode == meshtastic_Config_PositionConfig_GpsMode_ENABLED) && (gnssModel == GNSS_MODEL_UBLOX)) {
|
||||
// reset the GPS on next bootup
|
||||
if (devicestate.did_gps_reset && (millis() - lastWakeStartMsec > 60000) && !hasFlow()) {
|
||||
LOG_DEBUG("GPS is not communicating, trying factory reset on next bootup.\n");
|
||||
@@ -682,7 +678,8 @@ int32_t GPS::runOnce()
|
||||
// At least one GPS has a bad habit of losing its mind from time to time
|
||||
if (rebootsSeen > 2) {
|
||||
rebootsSeen = 0;
|
||||
gps->factoryReset();
|
||||
LOG_DEBUG("Would normally factoryReset()\n");
|
||||
// gps->factoryReset();
|
||||
}
|
||||
|
||||
// If we are overdue for an update, turn on the GPS and at least publish the current status
|
||||
@@ -908,7 +905,7 @@ 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)
|
||||
#if HAS_GPS && !defined(ARCH_ESP32)
|
||||
_rx_gpio = 1; // We only specify GPS serial ports on ESP32. Otherwise, these are just flags.
|
||||
_tx_gpio = 1;
|
||||
#endif
|
||||
@@ -1104,7 +1101,7 @@ bool GPS::lookForLocation()
|
||||
|
||||
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
|
||||
fixType = atoi(gsafixtype.value()); // will set to zero if no data
|
||||
// LOG_DEBUG("FIX QUAL=%d, TYPE=%d\n", fixQual, fixType);
|
||||
// LOG_DEBUG("FIX QUAL=%d, TYPE=%d\n", fixQual, fixType);
|
||||
#endif
|
||||
|
||||
// check if GPS has an acceptable lock
|
||||
@@ -1121,6 +1118,10 @@ bool GPS::lookForLocation()
|
||||
reader.date.age(), reader.time.age());
|
||||
#endif // GPS_EXTRAVERBOSE
|
||||
|
||||
// Is this a new point or are we re-reading the previous one?
|
||||
if (!reader.location.isUpdated())
|
||||
return false;
|
||||
|
||||
// check if a complete GPS solution set is available for reading
|
||||
// tinyGPSDatum::age() also includes isValid() test
|
||||
// FIXME
|
||||
@@ -1133,10 +1134,6 @@ bool GPS::lookForLocation()
|
||||
return false;
|
||||
}
|
||||
|
||||
// Is this a new point or are we re-reading the previous one?
|
||||
if (!reader.location.isUpdated())
|
||||
return false;
|
||||
|
||||
// We know the solution is fresh and valid, so just read the data
|
||||
auto loc = reader.location.value();
|
||||
|
||||
@@ -1286,4 +1283,17 @@ int32_t GPS::disable()
|
||||
setAwake(false);
|
||||
|
||||
return INT32_MAX;
|
||||
}
|
||||
|
||||
void GPS::toggleGpsMode()
|
||||
{
|
||||
if (config.position.gps_mode == meshtastic_Config_PositionConfig_GpsMode_ENABLED) {
|
||||
config.position.gps_mode = meshtastic_Config_PositionConfig_GpsMode_DISABLED;
|
||||
LOG_DEBUG("Flag set to false for gps power. GpsMode: DISABLED\n");
|
||||
disable();
|
||||
} else if (config.position.gps_mode == meshtastic_Config_PositionConfig_GpsMode_DISABLED) {
|
||||
config.position.gps_mode = meshtastic_Config_PositionConfig_GpsMode_ENABLED;
|
||||
LOG_DEBUG("Flag set to true to restore power. GpsMode: ENABLED\n");
|
||||
enable();
|
||||
}
|
||||
}
|
||||
@@ -103,11 +103,12 @@ class GPS : private concurrency::OSThread
|
||||
static const uint8_t _message_JAM[];
|
||||
static const uint8_t _message_NAVX5[];
|
||||
static const uint8_t _message_1HZ[];
|
||||
static const uint8_t _message_GGL[];
|
||||
static const uint8_t _message_GLL[];
|
||||
static const uint8_t _message_GSA[];
|
||||
static const uint8_t _message_GSV[];
|
||||
static const uint8_t _message_VTG[];
|
||||
static const uint8_t _message_RMC[];
|
||||
static const uint8_t _message_AID[];
|
||||
static const uint8_t _message_GGA[];
|
||||
static const uint8_t _message_PMS[];
|
||||
static const uint8_t _message_SAVE[];
|
||||
@@ -132,6 +133,9 @@ class GPS : private concurrency::OSThread
|
||||
// Disable the thread
|
||||
int32_t disable() override;
|
||||
|
||||
// toggle between enabled/disabled
|
||||
void toggleGpsMode();
|
||||
|
||||
void setGPSPower(bool on, bool standbyOnly, uint32_t sleepTime);
|
||||
|
||||
/// Returns true if we have acquired GPS lock.
|
||||
@@ -143,7 +147,7 @@ class GPS : private concurrency::OSThread
|
||||
/// Return true if we are connected to a GPS
|
||||
bool isConnected() const { return hasGPS; }
|
||||
|
||||
bool isPowerSaving() const { return !config.position.gps_enabled; }
|
||||
bool isPowerSaving() const { return config.position.gps_mode != meshtastic_Config_PositionConfig_GpsMode_ENABLED; }
|
||||
|
||||
// Empty the input buffer as quickly as possible
|
||||
void clearBuffer();
|
||||
|
||||
204
src/gps/ubx.h
204
src/gps/ubx.h
@@ -10,24 +10,32 @@ const uint8_t GPS::_message_CFG_RXM_PSM[] PROGMEM = {
|
||||
0x01 // Power save mode
|
||||
};
|
||||
|
||||
// only for Neo-6
|
||||
const uint8_t GPS::_message_CFG_RXM_ECO[] PROGMEM = {
|
||||
0x08, // Reserved
|
||||
0x04 // eco mode
|
||||
};
|
||||
|
||||
const uint8_t GPS::_message_CFG_PM2[] PROGMEM = {
|
||||
0x01, 0x06, 0x00, 0x00, // version, Reserved
|
||||
0x0E, 0x81, 0x43, 0x01, // flags
|
||||
0x01, // version
|
||||
0x00, // Reserved 1, set to 0x06 by u-Center
|
||||
0x00, // Reserved 2
|
||||
0x00, // Reserved 1
|
||||
0x00, 0x11, 0x03, 0x00, // flags-> cyclic mode, wait for normal fix ok, do not wake to update RTC or EPH, doNotEnterOff,
|
||||
// LimitPeakCurrent
|
||||
0xE8, 0x03, 0x00, 0x00, // update period 1000 ms
|
||||
0x10, 0x27, 0x00, 0x00, // search period 10s
|
||||
0x00, 0x00, 0x00, 0x00, // Grod offset 0
|
||||
0x00, 0x00, 0x00, 0x00, // Grid offset 0
|
||||
0x01, 0x00, // onTime 1 second
|
||||
0x00, 0x00, // min search time 0
|
||||
0x2C, 0x01, // reserved
|
||||
0x00, 0x00, 0x4F, 0xC1, // reserved
|
||||
0x03, 0x00, 0x87, 0x02, // reserved
|
||||
0x00, 0x00, 0xFF, 0x00, // reserved
|
||||
0x01, 0x00, 0xD6, 0x4D // reserved
|
||||
0x00, 0x00, // 0x2C, 0x01, // reserved 4
|
||||
0x00, 0x00, // 0x00, 0x00, // reserved 5
|
||||
0x00, 0x00, 0x00, 0x00, // 0x4F, 0xC1, 0x03, 0x00, // reserved 6
|
||||
0x00, 0x00, 0x00, 0x00, // 0x87, 0x02, 0x00, 0x00, // reserved 7
|
||||
0x00, // 0xFF, // reserved 8
|
||||
0x00, // 0x00, // reserved 9
|
||||
0x00, 0x00, // 0x00, 0x00, // reserved 10
|
||||
0x00, 0x00, 0x00, 0x00 // 0x64, 0x40, 0x01, 0x00 // reserved 11
|
||||
};
|
||||
|
||||
const uint8_t GPS::_message_GNSS_7[] = {
|
||||
@@ -56,52 +64,59 @@ const uint8_t GPS::_message_GNSS[] = {
|
||||
0x01, 0x01, 0x03, 0x00, 0x01, 0x00, 0x01, 0x01, // SBAS
|
||||
0x06, 0x08, 0x0e, 0x00, 0x01, 0x00, 0x01, 0x01 // GLONASS
|
||||
};
|
||||
// Enable jamming/interference monitor
|
||||
|
||||
// Enable interference resistance, because we are using LoRa, WiFi and Bluetooth on same board,
|
||||
// and we need to reduce interference from them
|
||||
// For Neo-6
|
||||
const uint8_t GPS::_message_JAM[] = {
|
||||
// bbThreshold (Broadband jamming detection threshold) is set to 0x3F (63 in decimal)
|
||||
// cwThreshold (CW jamming detection threshold) is set to 0x10 (16 in decimal)
|
||||
// algorithmBits (Reserved algorithm settings) is set to 0x16B156 as recommended
|
||||
// enable (Enable interference detection) is set to 1 (enabled)
|
||||
0x3F, 0x10, 0xB1, 0x56, // config: Interference config word
|
||||
// generalBits (General settings) is set to 0x31E as recommended
|
||||
// antSetting (Antenna setting, 0=unknown, 1=passive, 2=active) is set to 0 (unknown)
|
||||
// ToDo: Set to 1 (passive) or 2 (active) if known, for example from UBX-MON-HW, or from board info
|
||||
// enable2 (Set to 1 to scan auxiliary bands, u-blox 8 / u-blox M8 only, otherwise ignored) is set to 1
|
||||
// (enabled)
|
||||
0x1E, 0x03, 0x00, 0x01 // config2: Extra settings for jamming/interference monitor
|
||||
0xf3, 0xac, 0x62, 0xad, // config1 bbThreshold = 3, cwThreshold = 15, enable = 1, reserved bits 0x16B156
|
||||
0x1e, 0x03, 0x00, 0x00 // config2 antennaSetting Unknown = 0, reserved 3, = 0x00,0x00, reserved 2 = 0x31E
|
||||
};
|
||||
/* // WIP GPS reconfig
|
||||
// For Neo-6, Max-7 and Neo-7
|
||||
const uint8_t GPS::_message_JAM_6_7[] = {
|
||||
0xf3, 0xac, 0x62, 0xad, // config1 bbThreshold = 3, cwThreshold = 15, enable = 1, reserved bits 0x16B156
|
||||
0x1e, 0x03, 0x00, 0x00 // config2 antennaSetting Unknown = 0, reserved 3, = 0x00,0x00, reserved 2 = 0x31E
|
||||
};
|
||||
|
||||
// For M8
|
||||
const uint8_t GPS::_message_JAM_8[] = {
|
||||
0xf3, 0xac, 0x62, 0xad, // config1 bbThreshold = 3, cwThreshold = 15, enable1 = 1, reserved bits 0x16B156
|
||||
0x1e, 0x43, 0x00, 0x00 // config2 antennaSetting Unknown = 0, enable2 = 1, generalBits = 0x31E
|
||||
};
|
||||
*/
|
||||
|
||||
// Configure navigation engine expert settings:
|
||||
// there are many variations of what were Reserved fields for the Neo-6 in later versions
|
||||
// ToDo: check UBX-MON-VER for module type and protocol version
|
||||
|
||||
// For the Neo-6
|
||||
const uint8_t GPS::_message_NAVX5[] = {
|
||||
0x00, 0x00, // msgVer (0 for this version)
|
||||
// minMax flag = 1: apply min/max SVs settings
|
||||
// minCno flag = 1: apply minimum C/N0 setting
|
||||
// initial3dfix flag = 0: apply initial 3D fix settings
|
||||
// aop flag = 1: apply aopCfg (useAOP flag) settings (AssistNow Autonomous)
|
||||
0x1B, 0x00, // mask1 (First parameters bitmask)
|
||||
// adr flag = 0: apply ADR sensor fusion on/off setting (useAdr flag)
|
||||
// If firmware is not ADR/UDR, enabling this flag will fail configuration
|
||||
// ToDo: check this with UBX-MON-VER
|
||||
0x00, 0x00, 0x00, 0x00, // mask2 (Second parameters bitmask)
|
||||
0x00, 0x00, // Reserved
|
||||
0x03, // minSVs (Minimum number of satellites for navigation) = 3
|
||||
0x10, // maxSVs (Maximum number of satellites for navigation) = 16
|
||||
0x06, // minCNO (Minimum satellite signal level for navigation) = 6 dBHz
|
||||
0x00, // Reserved
|
||||
0x00, // iniFix3D (Initial fix must be 3D) = 0 (disabled)
|
||||
0x00, 0x00, // Reserved
|
||||
0x00, // ackAiding (Issue acknowledgements for assistance message input) = 0 (disabled)
|
||||
0x00, 0x00, // Reserved
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Reserved
|
||||
0x00, // Reserved
|
||||
0x01, // aopCfg (AssistNow Autonomous configuration) = 1 (enabled)
|
||||
0x00, 0x00, // Reserved
|
||||
0x00, 0x00, // Reserved
|
||||
0x00, 0x00, 0x00, 0x00, // Reserved
|
||||
0x00, 0x00, 0x00, // Reserved
|
||||
0x01, // useAdr (Enable/disable ADR sensor fusion) = 1 (enabled)
|
||||
0x00, 0x00, // msgVer (0 for this version)
|
||||
0x4c, 0x66, // mask1
|
||||
0x00, 0x00, 0x00, 0x00, // Reserved 0
|
||||
0x00, // Reserved 1
|
||||
0x00, // Reserved 2
|
||||
0x03, // minSVs (Minimum number of satellites for navigation) = 3
|
||||
0x10, // maxSVs (Maximum number of satellites for navigation) = 16
|
||||
0x06, // minCNO (Minimum satellite signal level for navigation) = 6 dBHz
|
||||
0x00, // Reserved 5
|
||||
0x00, // iniFix3D (Initial fix must be 3D) (0 = false 1 = true)
|
||||
0x00, // Reserved 6
|
||||
0x00, // Reserved 7
|
||||
0x00, // Reserved 8
|
||||
0x00, 0x00, // wknRollover 0 = firmware default
|
||||
0x00, 0x00, 0x00, 0x00, // Reserved 9
|
||||
0x00, // Reserved 10
|
||||
0x00, // Reserved 11
|
||||
0x00, // usePPP (Precice Point Positioning) (0 = false, 1 = true)
|
||||
0x01, // useAOP (AssistNow Autonomous configuration) = 1 (enabled)
|
||||
0x00, // Reserved 12
|
||||
0x00, // Reserved 13
|
||||
0x00, 0x00, // aopOrbMaxErr = 0 to reset to firmware default
|
||||
0x00, // Reserved 14
|
||||
0x00, // Reserved 15
|
||||
0x00, 0x00, // Reserved 3
|
||||
0x00, 0x00, 0x00, 0x00 // Reserved 4
|
||||
};
|
||||
|
||||
// Set GPS update rate to 1Hz
|
||||
@@ -111,58 +126,88 @@ const uint8_t GPS::_message_NAVX5[] = {
|
||||
const uint8_t GPS::_message_1HZ[] = {
|
||||
0xE8, 0x03, // Measurement Rate (1000ms for 1Hz)
|
||||
0x01, 0x00, // Navigation rate, always 1 in GPS mode
|
||||
0x01, 0x00, // Time reference
|
||||
0x01, 0x00 // Time reference
|
||||
};
|
||||
|
||||
// Disable GGL. GGL - Geographic position (latitude and longitude), which provides the current geographical
|
||||
// Disable GLL. GLL - Geographic position (latitude and longitude), which provides the current geographical
|
||||
// coordinates.
|
||||
const uint8_t GPS::_message_GGL[] = {
|
||||
0xF0, 0x01, // NMEA ID for GLL
|
||||
0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI
|
||||
0x00, // Disable
|
||||
0x01, 0x01, 0x01, 0x01 // Reserved
|
||||
const uint8_t GPS::_message_GLL[] = {
|
||||
0xF0, 0x01, // NMEA ID for GLL
|
||||
0x00, // Rate for DDC
|
||||
0x00, // Rate for UART1
|
||||
0x00, // Rate for UART2
|
||||
0x00, // Rate for USB
|
||||
0x00, // Rate for SPI
|
||||
0x00 // Reserved
|
||||
};
|
||||
|
||||
// Enable GSA. GSA - GPS DOP and active satellites, used for detailing the satellites used in the positioning and
|
||||
// the DOP (Dilution of Precision)
|
||||
const uint8_t GPS::_message_GSA[] = {
|
||||
0xF0, 0x02, // NMEA ID for GSA
|
||||
0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI
|
||||
0x01, // Enable
|
||||
0x01, 0x01, 0x01, 0x01 // Reserved
|
||||
0xF0, 0x02, // NMEA ID for GSA
|
||||
0x00, // Rate for DDC
|
||||
0x01, // Rate for UART1
|
||||
0x00, // Rate for UART2
|
||||
0x00, // Rate for USB
|
||||
0x00, // Rate for SPI
|
||||
0x00 // Reserved
|
||||
};
|
||||
|
||||
// Disable GSV. GSV - Satellites in view, details the number and location of satellites in view.
|
||||
const uint8_t GPS::_message_GSV[] = {
|
||||
0xF0, 0x03, // NMEA ID for GSV
|
||||
0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI
|
||||
0x00, // Disable
|
||||
0x01, 0x01, 0x01, 0x01 // Reserved
|
||||
0xF0, 0x03, // NMEA ID for GSV
|
||||
0x00, // Rate for DDC
|
||||
0x00, // Rate for UART1
|
||||
0x00, // Rate for UART2
|
||||
0x00, // Rate for USB
|
||||
0x00, // Rate for SPI
|
||||
0x00 // Reserved
|
||||
};
|
||||
|
||||
// Disable VTG. VTG - Track made good and ground speed, which provides course and speed information relative to
|
||||
// the ground.
|
||||
const uint8_t GPS::_message_VTG[] = {
|
||||
0xF0, 0x05, // NMEA ID for VTG
|
||||
0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI
|
||||
0x00, // Disable
|
||||
0x01, 0x01, 0x01, 0x01 // Reserved
|
||||
0xF0, 0x05, // NMEA ID for VTG
|
||||
0x00, // Rate for DDC
|
||||
0x00, // Rate for UART1
|
||||
0x00, // Rate for UART2
|
||||
0x00, // Rate for USB
|
||||
0x00, // Rate for SPI
|
||||
0x00 // Reserved
|
||||
};
|
||||
|
||||
// Enable RMC. RMC - Recommended Minimum data, the essential gps pvt (position, velocity, time) data.
|
||||
const uint8_t GPS::_message_RMC[] = {
|
||||
0xF0, 0x04, // NMEA ID for RMC
|
||||
0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI
|
||||
0x01, // Enable
|
||||
0x01, 0x01, 0x01, 0x01 // Reserved
|
||||
0xF0, 0x04, // NMEA ID for RMC
|
||||
0x00, // Rate for DDC
|
||||
0x01, // Rate for UART1
|
||||
0x00, // Rate for UART2
|
||||
0x00, // Rate for USB
|
||||
0x00, // Rate for SPI
|
||||
0x00 // Reserved
|
||||
};
|
||||
|
||||
// Enable GGA. GGA - Global Positioning System Fix Data, which provides 3D location and accuracy data.
|
||||
const uint8_t GPS::_message_GGA[] = {
|
||||
0xF0, 0x00, // NMEA ID for GGA
|
||||
0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI
|
||||
0x01, // Enable
|
||||
0x01, 0x01, 0x01, 0x01 // Reserved
|
||||
0xF0, 0x00, // NMEA ID for GGA
|
||||
0x00, // Rate for DDC
|
||||
0x01, // Rate for UART1
|
||||
0x00, // Rate for UART2
|
||||
0x00, // Rate for USB
|
||||
0x00, // Rate for SPI
|
||||
0x00 // Reserved
|
||||
};
|
||||
|
||||
// Disable UBX-AID-ALPSRV as it may confuse TinyGPS. The Neo-6 seems to send this message
|
||||
// whether the AID Autonomous is enabled or not
|
||||
const uint8_t GPS::_message_AID[] = {
|
||||
0x0B, 0x32, // NMEA ID for UBX-AID-ALPSRV
|
||||
0x00, // Rate for DDC
|
||||
0x00, // Rate for UART1
|
||||
0x00, // Rate for UART2
|
||||
0x00, // Rate for USB
|
||||
0x00, // Rate for SPI
|
||||
0x00 // Reserved
|
||||
};
|
||||
|
||||
// The Power Management configuration allows the GPS module to operate in different power modes for optimized
|
||||
@@ -176,17 +221,18 @@ const uint8_t GPS::_message_GGA[] = {
|
||||
// is set to Interval; otherwise, it must be set to '0'. The 'onTime' field specifies the duration of the ON phase
|
||||
// and must be smaller than the period. It is only valid when the powerSetupValue is set to Interval; otherwise,
|
||||
// it must be set to '0'.
|
||||
// This command applies to M8 and higher products
|
||||
const uint8_t GPS::_message_PMS[] = {
|
||||
0x00, // Version (0)
|
||||
0x03, // Power setup value
|
||||
0x03, // Power setup value 3 = Agresssive 1Hz
|
||||
0x00, 0x00, // period: not applicable, set to 0
|
||||
0x00, 0x00, // onTime: not applicable, set to 0
|
||||
0x97, 0x6F // reserved, generated by u-center
|
||||
0x00, 0x00 // reserved, generated by u-center
|
||||
};
|
||||
|
||||
const uint8_t GPS::_message_SAVE[] = {
|
||||
0x00, 0x00, 0x00, 0x00, // clearMask: no sections cleared
|
||||
0xFF, 0xFF, 0x00, 0x00, // saveMask: save all sections
|
||||
0x00, 0x00, 0x00, 0x00, // loadMask: no sections loaded
|
||||
0x0F // deviceMask: BBR, Flash, EEPROM, and SPI Flash
|
||||
};
|
||||
0x17 // deviceMask: BBR, Flash, EEPROM, and SPI Flash
|
||||
};
|
||||
@@ -558,15 +558,20 @@ static void drawGPS(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus
|
||||
}
|
||||
}
|
||||
|
||||
// Draw status when gps is disabled by PMU
|
||||
// Draw status when GPS is disabled or not present
|
||||
static void drawGPSpowerstat(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus *gps)
|
||||
{
|
||||
String displayLine = "GPS disabled";
|
||||
int16_t xPos = display->getStringWidth(displayLine);
|
||||
|
||||
if (!config.position.gps_enabled) {
|
||||
display->drawString(x + xPos, y, displayLine);
|
||||
String displayLine;
|
||||
int pos;
|
||||
if (y < FONT_HEIGHT_SMALL) { // Line 1: use short string
|
||||
displayLine = config.position.gps_mode == meshtastic_Config_PositionConfig_GpsMode_NOT_PRESENT ? "No GPS" : "GPS off";
|
||||
pos = SCREEN_WIDTH - display->getStringWidth(displayLine);
|
||||
} else {
|
||||
displayLine = config.position.gps_mode == meshtastic_Config_PositionConfig_GpsMode_NOT_PRESENT ? "GPS not present"
|
||||
: "GPS is disabled";
|
||||
pos = (SCREEN_WIDTH - display->getStringWidth(displayLine)) / 2;
|
||||
}
|
||||
display->drawString(x + pos, y, displayLine);
|
||||
}
|
||||
|
||||
static void drawGPSAltitude(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus *gps)
|
||||
@@ -594,7 +599,7 @@ static void drawGPScoordinates(OLEDDisplay *display, int16_t x, int16_t y, const
|
||||
String displayLine = "";
|
||||
|
||||
if (!gps->getIsConnected() && !config.position.fixed_position) {
|
||||
displayLine = "No GPS Module";
|
||||
displayLine = "No GPS present";
|
||||
display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(displayLine))) / 2, y, displayLine);
|
||||
} else if (!gps->getHasLock() && !config.position.fixed_position) {
|
||||
displayLine = "No GPS Lock";
|
||||
@@ -1549,7 +1554,7 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
|
||||
drawNodes(display, x + (SCREEN_WIDTH * 0.25), y + 3, nodeStatus);
|
||||
}
|
||||
// Display GPS status
|
||||
if (!config.position.gps_enabled) {
|
||||
if (config.position.gps_mode != meshtastic_Config_PositionConfig_GpsMode_ENABLED) {
|
||||
drawGPSpowerstat(display, x, y + 2, gpsStatus);
|
||||
} else {
|
||||
if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT) {
|
||||
@@ -1777,7 +1782,7 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
|
||||
char chUtil[13];
|
||||
snprintf(chUtil, sizeof(chUtil), "ChUtil %2.0f%%", airTime->channelUtilizationPercent());
|
||||
display->drawString(x + SCREEN_WIDTH - display->getStringWidth(chUtil), y + FONT_HEIGHT_SMALL * 1, chUtil);
|
||||
if (config.position.gps_enabled) {
|
||||
if (config.position.gps_mode == meshtastic_Config_PositionConfig_GpsMode_ENABLED) {
|
||||
// Line 3
|
||||
if (config.display.gps_format !=
|
||||
meshtastic_Config_DisplayConfig_GpsCoordinateFormat_DMS) // if DMS then don't draw altitude
|
||||
@@ -1786,10 +1791,7 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
|
||||
// Line 4
|
||||
drawGPScoordinates(display, x, y + FONT_HEIGHT_SMALL * 3, gpsStatus);
|
||||
} else {
|
||||
drawGPSpowerstat(display, x - (SCREEN_WIDTH / 4), y + FONT_HEIGHT_SMALL * 2, gpsStatus);
|
||||
#ifdef GPS_POWER_TOGGLE
|
||||
display->drawString(x + 30, (y + FONT_HEIGHT_SMALL * 3), " by button");
|
||||
#endif
|
||||
drawGPSpowerstat(display, x, y + FONT_HEIGHT_SMALL * 2, gpsStatus);
|
||||
}
|
||||
/* Display a heartbeat pixel that blinks every time the frame is redrawn */
|
||||
#ifdef SHOW_REDRAWS
|
||||
|
||||
@@ -19,6 +19,10 @@
|
||||
#define TFT_BL ST7735_BACKLIGHT_EN
|
||||
#endif
|
||||
|
||||
#ifndef TFT_INVERT
|
||||
#define TFT_INVERT true
|
||||
#endif
|
||||
|
||||
class LGFX : public lgfx::LGFX_Device
|
||||
{
|
||||
lgfx::Panel_ST7735S _panel_instance;
|
||||
@@ -68,7 +72,7 @@ class LGFX : public lgfx::LGFX_Device
|
||||
cfg.dummy_read_pixel = 8; // Number of bits for dummy read before pixel readout
|
||||
cfg.dummy_read_bits = 1; // Number of bits for dummy read before non-pixel data read
|
||||
cfg.readable = true; // Set to true if data can be read
|
||||
cfg.invert = true; // Set to true if the light/darkness of the panel is reversed
|
||||
cfg.invert = TFT_INVERT; // Set to true if the light/darkness of the panel is reversed
|
||||
cfg.rgb_order = false; // Set to true if the panel's red and blue are swapped
|
||||
cfg.dlen_16bit =
|
||||
false; // Set to true for panels that transmit data length in 16-bit units with 16-bit parallel or SPI
|
||||
@@ -598,7 +602,7 @@ bool TFTDisplay::connect()
|
||||
tft->setRotation(1);
|
||||
tft->setSwapBytes(true);
|
||||
// tft->fillScreen(TFT_BLACK);
|
||||
#elif defined(T_DECK) || defined(PICOMPUTER_S3)
|
||||
#elif defined(T_DECK) || defined(PICOMPUTER_S3) || defined(CHATTER_2)
|
||||
tft->setRotation(1); // T-Deck has the TFT in landscape
|
||||
#elif defined(T_WATCH_S3)
|
||||
tft->setRotation(2); // T-Watch S3 left-handed orientation
|
||||
|
||||
26
src/main.cpp
26
src/main.cpp
@@ -248,6 +248,11 @@ void setup()
|
||||
digitalWrite(PIN_EINK_PWR_ON, HIGH);
|
||||
#endif
|
||||
|
||||
#if defined(LORA_TCXO_GPIO)
|
||||
pinMode(LORA_TCXO_GPIO, OUTPUT);
|
||||
digitalWrite(LORA_TCXO_GPIO, HIGH);
|
||||
#endif
|
||||
|
||||
#ifdef ST7735_BL_V03 // Heltec Wireless Tracker PCB Change Detect/Hack
|
||||
|
||||
rtc_clk_32k_enable(true);
|
||||
@@ -363,6 +368,13 @@ void setup()
|
||||
Wire.begin();
|
||||
#elif defined(I2C_SDA) && !defined(ARCH_RP2040)
|
||||
Wire.begin(I2C_SDA, I2C_SCL);
|
||||
#elif defined(ARCH_PORTDUINO)
|
||||
if (settingsStrings[i2cdev] != "") {
|
||||
LOG_INFO("Using %s as I2C device.\n", settingsStrings[i2cdev]);
|
||||
Wire.begin(settingsStrings[i2cdev].c_str());
|
||||
} else {
|
||||
LOG_INFO("No I2C device configured, skipping.\n");
|
||||
}
|
||||
#elif HAS_WIRE
|
||||
Wire.begin();
|
||||
#endif
|
||||
@@ -408,8 +420,9 @@ void setup()
|
||||
// We need to scan here to decide if we have a screen for nodeDB.init() and because power has been applied to
|
||||
// accessories
|
||||
auto i2cScanner = std::unique_ptr<ScanI2CTwoWire>(new ScanI2CTwoWire());
|
||||
|
||||
#ifdef HAS_WIRE
|
||||
LOG_INFO("Scanning for i2c devices...\n");
|
||||
#endif
|
||||
|
||||
#if defined(I2C_SDA1) && defined(ARCH_RP2040)
|
||||
Wire1.setSDA(I2C_SDA1);
|
||||
@@ -429,6 +442,11 @@ void setup()
|
||||
#elif defined(I2C_SDA) && !defined(ARCH_RP2040)
|
||||
Wire.begin(I2C_SDA, I2C_SCL);
|
||||
i2cScanner->scanPort(ScanI2C::I2CPort::WIRE);
|
||||
#elif defined(ARCH_PORTDUINO)
|
||||
if (settingsStrings[i2cdev] != "") {
|
||||
LOG_INFO("Scanning for i2c devices...\n");
|
||||
i2cScanner->scanPort(ScanI2C::I2CPort::WIRE);
|
||||
}
|
||||
#elif HAS_WIRE
|
||||
i2cScanner->scanPort(ScanI2C::I2CPort::WIRE);
|
||||
#endif
|
||||
@@ -667,7 +685,8 @@ void setup()
|
||||
readFromRTC(); // read the main CPU RTC at first (in case we can't get GPS time)
|
||||
|
||||
// If we're taking on the repeater role, ignore GPS
|
||||
if (config.device.role != meshtastic_Config_DeviceConfig_Role_REPEATER) {
|
||||
if (config.device.role != meshtastic_Config_DeviceConfig_Role_REPEATER &&
|
||||
config.position.gps_mode != meshtastic_Config_PositionConfig_GpsMode_NOT_PRESENT) {
|
||||
gps = GPS::createGps();
|
||||
}
|
||||
if (gps) {
|
||||
@@ -717,6 +736,7 @@ void setup()
|
||||
#ifdef ARCH_PORTDUINO
|
||||
if (settingsMap[use_sx1262]) {
|
||||
if (!rIf) {
|
||||
LOG_DEBUG("Attempting to activate sx1262 radio on SPI port %s\n", settingsStrings[spidev].c_str());
|
||||
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI, spiSettings);
|
||||
rIf = new SX1262Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
|
||||
settingsMap[busy]);
|
||||
@@ -730,6 +750,7 @@ void setup()
|
||||
}
|
||||
} else if (settingsMap[use_rf95]) {
|
||||
if (!rIf) {
|
||||
LOG_DEBUG("Attempting to activate rf95 radio on SPI port %s\n", settingsStrings[spidev].c_str());
|
||||
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI, spiSettings);
|
||||
rIf = new RF95Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
|
||||
settingsMap[busy]);
|
||||
@@ -744,6 +765,7 @@ void setup()
|
||||
}
|
||||
} else if (settingsMap[use_sx1280]) {
|
||||
if (!rIf) {
|
||||
LOG_DEBUG("Attempting to activate sx1280 radio on SPI port %s\n", settingsStrings[spidev].c_str());
|
||||
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI, spiSettings);
|
||||
rIf = new SX1280Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
|
||||
settingsMap[busy]);
|
||||
|
||||
@@ -15,6 +15,7 @@ Channels channels;
|
||||
const char *Channels::adminChannel = "admin";
|
||||
const char *Channels::gpioChannel = "gpio";
|
||||
const char *Channels::serialChannel = "serial";
|
||||
const char *Channels::mqttChannel = "mqtt";
|
||||
|
||||
uint8_t xorHash(const uint8_t *p, size_t len)
|
||||
{
|
||||
@@ -313,4 +314,4 @@ bool Channels::decryptForHash(ChannelIndex chIndex, ChannelHash channelHash)
|
||||
int16_t Channels::setActiveByIndex(ChannelIndex channelIndex)
|
||||
{
|
||||
return setCrypto(channelIndex);
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,7 @@ class Channels
|
||||
Channels() {}
|
||||
|
||||
/// Well known channel names
|
||||
static const char *adminChannel, *gpioChannel, *serialChannel;
|
||||
static const char *adminChannel, *gpioChannel, *serialChannel, *mqttChannel;
|
||||
|
||||
const meshtastic_ChannelSettings &getPrimary() { return getByIndex(getPrimaryIndex()).settings; }
|
||||
|
||||
@@ -139,4 +139,4 @@ class Channels
|
||||
};
|
||||
|
||||
/// Singleton channel table
|
||||
extern Channels channels;
|
||||
extern Channels channels;
|
||||
@@ -108,8 +108,9 @@ void MeshService::loop()
|
||||
(void)sendQueueStatusToPhone(qs, 0, 0);
|
||||
}
|
||||
if (oldFromNum != fromNum) { // We don't want to generate extra notifies for multiple new packets
|
||||
fromNumChanged.notifyObservers(fromNum);
|
||||
oldFromNum = fromNum;
|
||||
int result = fromNumChanged.notifyObservers(fromNum);
|
||||
if (result == 0) // If any observer returns non-zero, we will try again
|
||||
oldFromNum = fromNum;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -182,7 +182,16 @@ void NodeDB::installDefaultConfig()
|
||||
#else
|
||||
config.device.disable_triple_click = true;
|
||||
#endif
|
||||
config.position.gps_enabled = true;
|
||||
#if !HAS_GPS || defined(T_DECK)
|
||||
config.position.gps_mode = meshtastic_Config_PositionConfig_GpsMode_NOT_PRESENT;
|
||||
#elif !defined(GPS_RX_PIN)
|
||||
if (config.position.rx_gpio == 0)
|
||||
config.position.gps_mode = meshtastic_Config_PositionConfig_GpsMode_NOT_PRESENT;
|
||||
else
|
||||
config.position.gps_mode = meshtastic_Config_PositionConfig_GpsMode_DISABLED;
|
||||
#else
|
||||
config.position.gps_mode = meshtastic_Config_PositionConfig_GpsMode_ENABLED;
|
||||
#endif
|
||||
config.position.position_broadcast_smart_enabled = true;
|
||||
config.position.broadcast_smart_minimum_distance = 100;
|
||||
config.position.broadcast_smart_minimum_interval_secs = 30;
|
||||
@@ -454,6 +463,11 @@ void NodeDB::init()
|
||||
memcpy(devicestate.node_remote_hardware_pins, empty, sizeof(empty));
|
||||
}
|
||||
|
||||
if (config.position.gps_enabled) {
|
||||
config.position.gps_mode = meshtastic_Config_PositionConfig_GpsMode_ENABLED;
|
||||
config.position.gps_enabled = 0;
|
||||
}
|
||||
|
||||
saveToDisk(saveWhat);
|
||||
}
|
||||
|
||||
@@ -879,10 +893,11 @@ meshtastic_NodeInfoLite *NodeDB::getOrCreateMeshNode(NodeNum n)
|
||||
if ((*numMeshNodes >= MAX_NUM_NODES) || (memGet.getFreeHeap() < meshtastic_NodeInfoLite_size * 3)) {
|
||||
if (screen)
|
||||
screen->print("warning: node_db_lite full! erasing oldest entry\n");
|
||||
LOG_INFO("warning: node_db_lite full! erasing oldest entry\n");
|
||||
// look for oldest node and erase it
|
||||
uint32_t oldest = UINT32_MAX;
|
||||
int oldestIndex = -1;
|
||||
for (int i = 0; i < *numMeshNodes; i++) {
|
||||
for (int i = 1; i < *numMeshNodes; i++) {
|
||||
if (meshNodes[i].last_heard < oldest) {
|
||||
oldest = meshNodes[i].last_heard;
|
||||
oldestIndex = i;
|
||||
@@ -926,4 +941,4 @@ void recordCriticalError(meshtastic_CriticalErrorCode code, uint32_t address, co
|
||||
LOG_ERROR("A critical failure occurred, portduino is exiting...");
|
||||
exit(2);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -62,15 +62,17 @@ void PhoneAPI::close()
|
||||
}
|
||||
}
|
||||
|
||||
void PhoneAPI::checkConnectionTimeout()
|
||||
bool PhoneAPI::checkConnectionTimeout()
|
||||
{
|
||||
if (isConnected()) {
|
||||
bool newContact = checkIsConnected();
|
||||
if (!newContact) {
|
||||
LOG_INFO("Lost phone connection\n");
|
||||
close();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -461,8 +463,8 @@ bool PhoneAPI::handleToRadioPacket(meshtastic_MeshPacket &p)
|
||||
/// If the mesh service tells us fromNum has changed, tell the phone
|
||||
int PhoneAPI::onNotify(uint32_t newValue)
|
||||
{
|
||||
checkConnectionTimeout(); // a handy place to check if we've heard from the phone (since the BLE version doesn't call this
|
||||
// from idle)
|
||||
bool timeout = checkConnectionTimeout(); // a handy place to check if we've heard from the phone (since the BLE version
|
||||
// doesn't call this from idle)
|
||||
|
||||
if (state == STATE_SEND_PACKETS) {
|
||||
LOG_INFO("Telling client we have new packets %u\n", newValue);
|
||||
@@ -471,5 +473,5 @@ int PhoneAPI::onNotify(uint32_t newValue)
|
||||
LOG_DEBUG("(Client not yet interested in packets)\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
return timeout ? -1 : 0; // If we timed out, MeshService should stop iterating through observers as we just removed one
|
||||
}
|
||||
@@ -108,8 +108,8 @@ class PhoneAPI
|
||||
/// Hookable to find out when connection changes
|
||||
virtual void onConnectionChanged(bool connected) {}
|
||||
|
||||
/// If we haven't heard from the other side in a while then say not connected
|
||||
void checkConnectionTimeout();
|
||||
/// If we haven't heard from the other side in a while then say not connected. Returns true if timeout occurred
|
||||
bool checkConnectionTimeout();
|
||||
|
||||
/// Check the current underlying physical link to see if the client is currently connected
|
||||
virtual bool checkIsConnected() = 0;
|
||||
@@ -142,4 +142,4 @@ class PhoneAPI
|
||||
|
||||
/// If the mesh service tells us fromNum has changed, tell the phone
|
||||
virtual int onNotify(uint32_t newValue) override;
|
||||
};
|
||||
};
|
||||
@@ -248,28 +248,21 @@ ErrorCode Router::send(meshtastic_MeshPacket *p)
|
||||
// If the packet is not yet encrypted, do so now
|
||||
if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
|
||||
ChannelIndex chIndex = p->channel; // keep as a local because we are about to change it
|
||||
|
||||
if (moduleConfig.mqtt.enabled) {
|
||||
|
||||
LOG_INFO("Should encrypt MQTT?: %d\n", moduleConfig.mqtt.encryption_enabled);
|
||||
|
||||
// the packet is currently in a decrypted state. send it now if they want decrypted packets
|
||||
if (mqtt && !moduleConfig.mqtt.encryption_enabled)
|
||||
mqtt->onSend(*p, chIndex);
|
||||
}
|
||||
meshtastic_MeshPacket *p_decoded = packetPool.allocCopy(*p);
|
||||
|
||||
auto encodeResult = perhapsEncode(p);
|
||||
if (encodeResult != meshtastic_Routing_Error_NONE) {
|
||||
packetPool.release(p_decoded);
|
||||
abortSendAndNak(encodeResult, p);
|
||||
return encodeResult; // FIXME - this isn't a valid ErrorCode
|
||||
}
|
||||
|
||||
if (moduleConfig.mqtt.enabled) {
|
||||
// the packet is now encrypted.
|
||||
// check if we should send encrypted packets to mqtt
|
||||
if (mqtt && moduleConfig.mqtt.encryption_enabled)
|
||||
mqtt->onSend(*p, chIndex);
|
||||
LOG_INFO("Should encrypt MQTT?: %d\n", moduleConfig.mqtt.encryption_enabled);
|
||||
if (mqtt)
|
||||
mqtt->onSend(*p, *p_decoded, chIndex);
|
||||
}
|
||||
packetPool.release(p_decoded);
|
||||
}
|
||||
|
||||
assert(iface); // This should have been detected already in sendLocal (or we just received a packet from outside)
|
||||
|
||||
@@ -134,6 +134,8 @@ typedef struct _meshtastic_AdminMessage {
|
||||
/* Enter (UF2) DFU mode
|
||||
Only implemented on NRF52 currently */
|
||||
bool enter_dfu_mode_request;
|
||||
/* Delete the file by the specified path from the device */
|
||||
char delete_file_request[201];
|
||||
/* Set the owner for this node */
|
||||
meshtastic_User set_owner;
|
||||
/* Set channels (using the new API).
|
||||
@@ -228,6 +230,7 @@ extern "C" {
|
||||
#define meshtastic_AdminMessage_get_node_remote_hardware_pins_request_tag 19
|
||||
#define meshtastic_AdminMessage_get_node_remote_hardware_pins_response_tag 20
|
||||
#define meshtastic_AdminMessage_enter_dfu_mode_request_tag 21
|
||||
#define meshtastic_AdminMessage_delete_file_request_tag 22
|
||||
#define meshtastic_AdminMessage_set_owner_tag 32
|
||||
#define meshtastic_AdminMessage_set_channel_tag 33
|
||||
#define meshtastic_AdminMessage_set_config_tag 34
|
||||
@@ -266,6 +269,7 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,set_ham_mode,set_ham_mode),
|
||||
X(a, STATIC, ONEOF, BOOL, (payload_variant,get_node_remote_hardware_pins_request,get_node_remote_hardware_pins_request), 19) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,get_node_remote_hardware_pins_response,get_node_remote_hardware_pins_response), 20) \
|
||||
X(a, STATIC, ONEOF, BOOL, (payload_variant,enter_dfu_mode_request,enter_dfu_mode_request), 21) \
|
||||
X(a, STATIC, ONEOF, STRING, (payload_variant,delete_file_request,delete_file_request), 22) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,set_owner,set_owner), 32) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,set_channel,set_channel), 33) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,set_config,set_config), 34) \
|
||||
|
||||
@@ -45,3 +45,4 @@ PB_BIND(meshtastic_Config_BluetoothConfig, meshtastic_Config_BluetoothConfig, AU
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -108,6 +108,15 @@ typedef enum _meshtastic_Config_PositionConfig_PositionFlags {
|
||||
meshtastic_Config_PositionConfig_PositionFlags_SPEED = 512
|
||||
} meshtastic_Config_PositionConfig_PositionFlags;
|
||||
|
||||
typedef enum _meshtastic_Config_PositionConfig_GpsMode {
|
||||
/* GPS is present but disabled */
|
||||
meshtastic_Config_PositionConfig_GpsMode_DISABLED = 0,
|
||||
/* GPS is present and enabled */
|
||||
meshtastic_Config_PositionConfig_GpsMode_ENABLED = 1,
|
||||
/* GPS is not present on the device */
|
||||
meshtastic_Config_PositionConfig_GpsMode_NOT_PRESENT = 2
|
||||
} meshtastic_Config_PositionConfig_GpsMode;
|
||||
|
||||
typedef enum _meshtastic_Config_NetworkConfig_AddressMode {
|
||||
/* obtain ip address via DHCP */
|
||||
meshtastic_Config_NetworkConfig_AddressMode_DHCP = 0,
|
||||
@@ -300,6 +309,8 @@ typedef struct _meshtastic_Config_PositionConfig {
|
||||
uint32_t broadcast_smart_minimum_interval_secs;
|
||||
/* (Re)define PIN_GPS_EN for your board. */
|
||||
uint32_t gps_en_gpio;
|
||||
/* Set where GPS is enabled, disabled, or not present */
|
||||
meshtastic_Config_PositionConfig_GpsMode gps_mode;
|
||||
} meshtastic_Config_PositionConfig;
|
||||
|
||||
/* Power Config\
|
||||
@@ -507,6 +518,10 @@ extern "C" {
|
||||
#define _meshtastic_Config_PositionConfig_PositionFlags_MAX meshtastic_Config_PositionConfig_PositionFlags_SPEED
|
||||
#define _meshtastic_Config_PositionConfig_PositionFlags_ARRAYSIZE ((meshtastic_Config_PositionConfig_PositionFlags)(meshtastic_Config_PositionConfig_PositionFlags_SPEED+1))
|
||||
|
||||
#define _meshtastic_Config_PositionConfig_GpsMode_MIN meshtastic_Config_PositionConfig_GpsMode_DISABLED
|
||||
#define _meshtastic_Config_PositionConfig_GpsMode_MAX meshtastic_Config_PositionConfig_GpsMode_NOT_PRESENT
|
||||
#define _meshtastic_Config_PositionConfig_GpsMode_ARRAYSIZE ((meshtastic_Config_PositionConfig_GpsMode)(meshtastic_Config_PositionConfig_GpsMode_NOT_PRESENT+1))
|
||||
|
||||
#define _meshtastic_Config_NetworkConfig_AddressMode_MIN meshtastic_Config_NetworkConfig_AddressMode_DHCP
|
||||
#define _meshtastic_Config_NetworkConfig_AddressMode_MAX meshtastic_Config_NetworkConfig_AddressMode_STATIC
|
||||
#define _meshtastic_Config_NetworkConfig_AddressMode_ARRAYSIZE ((meshtastic_Config_NetworkConfig_AddressMode)(meshtastic_Config_NetworkConfig_AddressMode_STATIC+1))
|
||||
@@ -543,6 +558,7 @@ extern "C" {
|
||||
#define meshtastic_Config_DeviceConfig_role_ENUMTYPE meshtastic_Config_DeviceConfig_Role
|
||||
#define meshtastic_Config_DeviceConfig_rebroadcast_mode_ENUMTYPE meshtastic_Config_DeviceConfig_RebroadcastMode
|
||||
|
||||
#define meshtastic_Config_PositionConfig_gps_mode_ENUMTYPE meshtastic_Config_PositionConfig_GpsMode
|
||||
|
||||
|
||||
#define meshtastic_Config_NetworkConfig_address_mode_ENUMTYPE meshtastic_Config_NetworkConfig_AddressMode
|
||||
@@ -562,7 +578,7 @@ 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, 0}
|
||||
#define meshtastic_Config_PositionConfig_init_default {0, 0, 0, 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, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN}
|
||||
#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}
|
||||
@@ -571,7 +587,7 @@ extern "C" {
|
||||
#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, 0}
|
||||
#define meshtastic_Config_PositionConfig_init_zero {0, 0, 0, 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, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN}
|
||||
#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}
|
||||
@@ -602,6 +618,7 @@ extern "C" {
|
||||
#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_PositionConfig_gps_mode_tag 13
|
||||
#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
|
||||
@@ -704,7 +721,8 @@ 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, gps_en_gpio, 12)
|
||||
X(a, STATIC, SINGULAR, UINT32, gps_en_gpio, 12) \
|
||||
X(a, STATIC, SINGULAR, UENUM, gps_mode, 13)
|
||||
#define meshtastic_Config_PositionConfig_CALLBACK NULL
|
||||
#define meshtastic_Config_PositionConfig_DEFAULT NULL
|
||||
|
||||
@@ -810,7 +828,7 @@ extern const pb_msgdesc_t meshtastic_Config_BluetoothConfig_msg;
|
||||
#define meshtastic_Config_LoRaConfig_size 80
|
||||
#define meshtastic_Config_NetworkConfig_IpV4Config_size 20
|
||||
#define meshtastic_Config_NetworkConfig_size 196
|
||||
#define meshtastic_Config_PositionConfig_size 60
|
||||
#define meshtastic_Config_PositionConfig_size 62
|
||||
#define meshtastic_Config_PowerConfig_size 40
|
||||
#define meshtastic_Config_size 199
|
||||
|
||||
@@ -818,4 +836,4 @@ extern const pb_msgdesc_t meshtastic_Config_BluetoothConfig_msg;
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -316,7 +316,7 @@ extern const pb_msgdesc_t meshtastic_NodeRemoteHardwarePin_msg;
|
||||
#define meshtastic_DeviceState_size 17062
|
||||
#define meshtastic_NodeInfoLite_size 153
|
||||
#define meshtastic_NodeRemoteHardwarePin_size 29
|
||||
#define meshtastic_OEMStore_size 3244
|
||||
#define meshtastic_OEMStore_size 3246
|
||||
#define meshtastic_PositionLite_size 28
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -180,7 +180,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 467
|
||||
#define meshtastic_LocalConfig_size 469
|
||||
#define meshtastic_LocalModuleConfig_size 631
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -71,6 +71,8 @@ typedef enum _meshtastic_HardwareModel {
|
||||
meshtastic_HardwareModel_SENSELORA_RP2040 = 27,
|
||||
/* Makerfabs SenseLoRA Industrial Monitor (ESP32-S3 + RFM96) */
|
||||
meshtastic_HardwareModel_SENSELORA_S3 = 28,
|
||||
/* Canary Radio Company - CanaryOne: https://canaryradio.io/products/canaryone */
|
||||
meshtastic_HardwareModel_CANARYONE = 29,
|
||||
/* ---------------------------------------------------------------------------
|
||||
Less common/prototype boards listed here (needs one more byte over the air)
|
||||
--------------------------------------------------------------------------- */
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "MeshService.h"
|
||||
#include "NodeDB.h"
|
||||
#include "PowerFSM.h"
|
||||
#include <FSCommon.h>
|
||||
#ifdef ARCH_ESP32
|
||||
#include "BleOta.h"
|
||||
#endif
|
||||
@@ -194,6 +195,15 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case meshtastic_AdminMessage_delete_file_request_tag: {
|
||||
LOG_DEBUG("Client is requesting to delete file: %s\n", r->delete_file_request);
|
||||
if (FSCom.remove(r->delete_file_request)) {
|
||||
LOG_DEBUG("Successfully deleted file\n");
|
||||
} else {
|
||||
LOG_DEBUG("Failed to delete file\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
#ifdef ARCH_PORTDUINO
|
||||
case meshtastic_AdminMessage_exit_simulator_tag:
|
||||
LOG_INFO("Exiting simulator\n");
|
||||
|
||||
@@ -204,6 +204,8 @@ int32_t PositionModule::runOnce()
|
||||
}
|
||||
|
||||
meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(nodeDB.getNodeNum());
|
||||
if (node == nullptr)
|
||||
return RUNONCE_INTERVAL;
|
||||
|
||||
// We limit our GPS broadcasts to a max rate
|
||||
uint32_t now = millis();
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#include "mesh/wifi/WiFiAPClient.h"
|
||||
#include <WiFi.h>
|
||||
#endif
|
||||
#include "mqtt/JSON.h"
|
||||
#include <assert.h>
|
||||
|
||||
const int reconnectMax = 5;
|
||||
@@ -49,8 +48,6 @@ void MQTT::onReceive(char *topic, byte *payload, size_t length)
|
||||
payloadStr[length] = 0; // null terminated string
|
||||
JSONValue *json_value = JSON::Parse(payloadStr);
|
||||
if (json_value != NULL) {
|
||||
LOG_INFO("JSON Received on MQTT, parsing..\n");
|
||||
|
||||
// check if it is a valid envelope
|
||||
JSONObject json;
|
||||
json = json_value->AsObject();
|
||||
@@ -61,22 +58,21 @@ void MQTT::onReceive(char *topic, byte *payload, size_t length)
|
||||
ptr = strtok(NULL, "/");
|
||||
}
|
||||
meshtastic_Channel sendChannel = channels.getByName(ptr);
|
||||
LOG_DEBUG("Found Channel name: %s (Index %d)\n", channels.getGlobalId(sendChannel.index), sendChannel.index);
|
||||
// We allow downlink JSON packets only on a channel named "mqtt"
|
||||
if (strncasecmp(channels.getGlobalId(sendChannel.index), Channels::mqttChannel, strlen(Channels::mqttChannel)) == 0 &&
|
||||
sendChannel.settings.downlink_enabled) {
|
||||
if (isValidJsonEnvelope(json)) {
|
||||
// this is a valid envelope
|
||||
if (json["type"]->AsString().compare("sendtext") == 0 && json["payload"]->IsString()) {
|
||||
std::string jsonPayloadStr = json["payload"]->AsString();
|
||||
LOG_INFO("JSON payload %s, length %u\n", jsonPayloadStr.c_str(), jsonPayloadStr.length());
|
||||
|
||||
if ((json.find("sender") != json.end()) && (json.find("payload") != json.end()) &&
|
||||
(json.find("type") != json.end()) && json["type"]->IsString() &&
|
||||
(json["type"]->AsString().compare("sendtext") == 0)) {
|
||||
// this is a valid envelope
|
||||
if (json["payload"]->IsString() && json["type"]->IsString() &&
|
||||
(json["sender"]->AsString().compare(owner.id) != 0)) {
|
||||
std::string jsonPayloadStr = json["payload"]->AsString();
|
||||
LOG_INFO("JSON payload %s, length %u\n", jsonPayloadStr.c_str(), jsonPayloadStr.length());
|
||||
|
||||
// construct protobuf data packet using TEXT_MESSAGE, send it to the mesh
|
||||
meshtastic_MeshPacket *p = router->allocForSending();
|
||||
p->decoded.portnum = meshtastic_PortNum_TEXT_MESSAGE_APP;
|
||||
p->channel = sendChannel.index;
|
||||
if (sendChannel.settings.downlink_enabled) {
|
||||
// construct protobuf data packet using TEXT_MESSAGE, send it to the mesh
|
||||
meshtastic_MeshPacket *p = router->allocForSending();
|
||||
p->decoded.portnum = meshtastic_PortNum_TEXT_MESSAGE_APP;
|
||||
p->channel = sendChannel.index;
|
||||
if (json.find("to") != json.end() && json["to"]->IsNumber())
|
||||
p->to = json["to"]->AsNumber();
|
||||
if (jsonPayloadStr.length() <= sizeof(p->decoded.payload.bytes)) {
|
||||
memcpy(p->decoded.payload.bytes, jsonPayloadStr.c_str(), jsonPayloadStr.length());
|
||||
p->decoded.payload.size = jsonPayloadStr.length();
|
||||
@@ -85,61 +81,63 @@ void MQTT::onReceive(char *topic, byte *payload, size_t length)
|
||||
} else {
|
||||
LOG_WARN("Received MQTT json payload too long, dropping\n");
|
||||
}
|
||||
} else {
|
||||
LOG_WARN("Received MQTT json payload on channel %s, but downlink is disabled, dropping\n",
|
||||
sendChannel.settings.name);
|
||||
}
|
||||
} else {
|
||||
LOG_DEBUG("JSON Ignoring downlink message we originally sent.\n");
|
||||
}
|
||||
} else if ((json.find("sender") != json.end()) && (json.find("payload") != json.end()) &&
|
||||
(json.find("type") != json.end()) && json["type"]->IsString() &&
|
||||
(json["type"]->AsString().compare("sendposition") == 0)) {
|
||||
// invent the "sendposition" type for a valid envelope
|
||||
if (json["payload"]->IsObject() && json["type"]->IsString() &&
|
||||
(json["sender"]->AsString().compare(owner.id) != 0)) {
|
||||
JSONObject posit;
|
||||
posit = json["payload"]->AsObject(); // get nested JSON Position
|
||||
meshtastic_Position pos = meshtastic_Position_init_default;
|
||||
pos.latitude_i = posit["latitude_i"]->AsNumber();
|
||||
pos.longitude_i = posit["longitude_i"]->AsNumber();
|
||||
pos.altitude = posit["altitude"]->AsNumber();
|
||||
pos.time = posit["time"]->AsNumber();
|
||||
} else if (json["type"]->AsString().compare("sendposition") == 0 && json["payload"]->IsObject()) {
|
||||
// invent the "sendposition" type for a valid envelope
|
||||
JSONObject posit;
|
||||
posit = json["payload"]->AsObject(); // get nested JSON Position
|
||||
meshtastic_Position pos = meshtastic_Position_init_default;
|
||||
if (posit.find("latitude_i") != posit.end() && posit["latitude_i"]->IsNumber())
|
||||
pos.latitude_i = posit["latitude_i"]->AsNumber();
|
||||
if (posit.find("longitude_i") != posit.end() && posit["longitude_i"]->IsNumber())
|
||||
pos.longitude_i = posit["longitude_i"]->AsNumber();
|
||||
if (posit.find("altitude") != posit.end() && posit["altitude"]->IsNumber())
|
||||
pos.altitude = posit["altitude"]->AsNumber();
|
||||
if (posit.find("time") != posit.end() && posit["time"]->IsNumber())
|
||||
pos.time = posit["time"]->AsNumber();
|
||||
|
||||
// construct protobuf data packet using POSITION, send it to the mesh
|
||||
meshtastic_MeshPacket *p = router->allocForSending();
|
||||
p->decoded.portnum = meshtastic_PortNum_POSITION_APP;
|
||||
p->channel = sendChannel.index;
|
||||
if (sendChannel.settings.downlink_enabled) {
|
||||
// construct protobuf data packet using POSITION, send it to the mesh
|
||||
meshtastic_MeshPacket *p = router->allocForSending();
|
||||
p->decoded.portnum = meshtastic_PortNum_POSITION_APP;
|
||||
p->channel = sendChannel.index;
|
||||
if (json.find("to") != json.end() && json["to"]->IsNumber())
|
||||
p->to = json["to"]->AsNumber();
|
||||
p->decoded.payload.size =
|
||||
pb_encode_to_bytes(p->decoded.payload.bytes, sizeof(p->decoded.payload.bytes),
|
||||
&meshtastic_Position_msg, &pos); // make the Data protobuf from position
|
||||
service.sendToMesh(p, RX_SRC_LOCAL);
|
||||
} else {
|
||||
LOG_WARN("Received MQTT json payload on channel %s, but downlink is disabled, dropping\n",
|
||||
sendChannel.settings.name);
|
||||
LOG_DEBUG("JSON Ignoring downlink message with unsupported type.\n");
|
||||
}
|
||||
} else {
|
||||
LOG_DEBUG("JSON Ignoring downlink message we originally sent.\n");
|
||||
LOG_ERROR("JSON Received payload on MQTT but not a valid envelope.\n");
|
||||
}
|
||||
} else {
|
||||
LOG_ERROR("JSON Received payload on MQTT but not a valid envelope\n");
|
||||
LOG_WARN("JSON downlink received on channel not called 'mqtt' or without downlink enabled.\n");
|
||||
}
|
||||
} else {
|
||||
// no json, this is an invalid payload
|
||||
LOG_ERROR("Invalid MQTT service envelope, topic %s, len %u!\n", topic, length);
|
||||
LOG_ERROR("JSON Received payload on MQTT but not a valid JSON\n");
|
||||
}
|
||||
delete json_value;
|
||||
} else {
|
||||
if (!pb_decode_from_bytes(payload, length, &meshtastic_ServiceEnvelope_msg, &e)) {
|
||||
if (length == 0) {
|
||||
LOG_WARN("Empty MQTT payload received, topic %s!\n", topic);
|
||||
return;
|
||||
} else if (!pb_decode_from_bytes(payload, length, &meshtastic_ServiceEnvelope_msg, &e)) {
|
||||
LOG_ERROR("Invalid MQTT service envelope, topic %s, len %u!\n", topic, length);
|
||||
return;
|
||||
} else {
|
||||
if (strcmp(e.gateway_id, owner.id) == 0)
|
||||
LOG_INFO("Ignoring downlink message we originally sent.\n");
|
||||
else {
|
||||
meshtastic_Channel ch = channels.getByName(e.channel_id);
|
||||
if (strcmp(e.gateway_id, owner.id) == 0) {
|
||||
// Generate an implicit ACK towards ourselves (handled and processed only locally!) for this message.
|
||||
// We do this because packets are not rebroadcasted back into MQTT anymore and we assume that at least one node
|
||||
// receives it when we get our own packet back. Then we'll stop our retransmissions.
|
||||
if (e.packet && getFrom(e.packet) == nodeDB.getNodeNum())
|
||||
routingModule->sendAckNak(meshtastic_Routing_Error_NONE, getFrom(e.packet), e.packet->id, ch.index);
|
||||
else
|
||||
LOG_INFO("Ignoring downlink message we originally sent.\n");
|
||||
} else {
|
||||
// Find channel by channel_id and check downlink_enabled
|
||||
meshtastic_Channel ch = channels.getByName(e.channel_id);
|
||||
if (strcmp(e.channel_id, channels.getGlobalId(ch.index)) == 0 && e.packet && ch.settings.downlink_enabled) {
|
||||
LOG_INFO("Received MQTT topic %s, len=%u\n", topic, length);
|
||||
meshtastic_MeshPacket *p = packetPool.allocCopy(*e.packet);
|
||||
@@ -463,7 +461,7 @@ void MQTT::publishQueuedMessages()
|
||||
}
|
||||
}
|
||||
|
||||
void MQTT::onSend(const meshtastic_MeshPacket &mp, ChannelIndex chIndex)
|
||||
void MQTT::onSend(const meshtastic_MeshPacket &mp, const meshtastic_MeshPacket &mp_decoded, ChannelIndex chIndex)
|
||||
{
|
||||
if (mp.via_mqtt)
|
||||
return; // Don't send messages that came from MQTT back into MQTT
|
||||
@@ -483,7 +481,13 @@ void MQTT::onSend(const meshtastic_MeshPacket &mp, ChannelIndex chIndex)
|
||||
meshtastic_ServiceEnvelope *env = mqttPool.allocZeroed();
|
||||
env->channel_id = (char *)channelId;
|
||||
env->gateway_id = owner.id;
|
||||
env->packet = (meshtastic_MeshPacket *)∓
|
||||
|
||||
if (moduleConfig.mqtt.encryption_enabled) {
|
||||
env->packet = (meshtastic_MeshPacket *)∓
|
||||
} else {
|
||||
env->packet = (meshtastic_MeshPacket *)&mp_decoded;
|
||||
}
|
||||
|
||||
LOG_DEBUG("MQTT onSend - Publishing portnum %i message\n", env->packet->decoded.portnum);
|
||||
|
||||
if (moduleConfig.mqtt.proxy_to_client_enabled || this->isConnectedDirectly()) {
|
||||
@@ -498,7 +502,7 @@ void MQTT::onSend(const meshtastic_MeshPacket &mp, ChannelIndex chIndex)
|
||||
|
||||
if (moduleConfig.mqtt.json_enabled) {
|
||||
// handle json topic
|
||||
auto jsonString = this->meshPacketToJson((meshtastic_MeshPacket *)&mp);
|
||||
auto jsonString = this->meshPacketToJson((meshtastic_MeshPacket *)&mp_decoded);
|
||||
if (jsonString.length() != 0) {
|
||||
std::string topicJson = jsonTopic + channelId + "/" + owner.id;
|
||||
LOG_INFO("JSON publish message to %s, %u bytes: %s\n", topicJson.c_str(), jsonString.length(),
|
||||
@@ -507,11 +511,6 @@ void MQTT::onSend(const meshtastic_MeshPacket &mp, ChannelIndex chIndex)
|
||||
}
|
||||
}
|
||||
|
||||
// Generate an implicit ACK towards ourselves (handled and processed only locally!) for this message.
|
||||
// We do this because packets are not rebroadcasted back into MQTT anymore and we assume that at least one node
|
||||
// receives it when we're connected to the broker. Then we'll stop our retransmissions.
|
||||
if (getFrom(&mp) == nodeDB.getNodeNum())
|
||||
routingModule->sendAckNak(meshtastic_Routing_Error_NONE, getFrom(&mp), mp.id, chIndex);
|
||||
} else {
|
||||
LOG_INFO("MQTT not connected, queueing packet\n");
|
||||
if (mqttQueue.numFree() == 0) {
|
||||
@@ -809,4 +808,14 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp)
|
||||
|
||||
delete value;
|
||||
return jsonStr;
|
||||
}
|
||||
|
||||
bool MQTT::isValidJsonEnvelope(JSONObject &json)
|
||||
{
|
||||
// if "sender" is provided, avoid processing packets we uplinked
|
||||
return (json.find("sender") != json.end() ? (json["sender"]->AsString().compare(owner.id) != 0) : true) &&
|
||||
(json.find("from") != json.end()) && json["from"]->IsNumber() &&
|
||||
(json["from"]->AsNumber() == nodeDB.getNodeNum()) && // only accept message if the "from" is us
|
||||
(json.find("type") != json.end()) && json["type"]->IsString() && // should specify a type
|
||||
(json.find("payload") != json.end()); // should have a payload
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "concurrency/OSThread.h"
|
||||
#include "mesh/Channels.h"
|
||||
#include "mesh/generated/meshtastic/mqtt.pb.h"
|
||||
#include "mqtt/JSON.h"
|
||||
#if HAS_WIFI
|
||||
#include <WiFiClient.h>
|
||||
#define HAS_NETWORKING 1
|
||||
@@ -48,14 +49,14 @@ class MQTT : private concurrency::OSThread
|
||||
MQTT();
|
||||
|
||||
/**
|
||||
* Publish a packet on the glboal MQTT server.
|
||||
* Publish a packet on the global MQTT server.
|
||||
* This hook must be called **after** the packet is encrypted (including the channel being changed to a hash).
|
||||
* @param chIndex the index of the channel for this message
|
||||
*
|
||||
* Note: for messages we are forwarding on the mesh that we can't find the channel for (because we don't have the keys), we
|
||||
* can not forward those messages to the cloud - because no way to find a global channel ID.
|
||||
*/
|
||||
void onSend(const meshtastic_MeshPacket &mp, ChannelIndex chIndex);
|
||||
void onSend(const meshtastic_MeshPacket &mp, const meshtastic_MeshPacket &mp_decoded, ChannelIndex chIndex);
|
||||
|
||||
/** Attempt to connect to server if necessary
|
||||
*/
|
||||
@@ -100,6 +101,9 @@ class MQTT : private concurrency::OSThread
|
||||
void publishStatus();
|
||||
void publishQueuedMessages();
|
||||
|
||||
// returns true if this is a valid JSON envelope which we accept on downlink
|
||||
bool isValidJsonEnvelope(JSONObject &json);
|
||||
|
||||
/// Return 0 if sleep is okay, veto sleep if we are connected to pubsub server
|
||||
// int preflightSleepCb(void *unused = NULL) { return pubSub.connected() ? 1 : 0; }
|
||||
};
|
||||
|
||||
@@ -125,6 +125,8 @@
|
||||
#define HW_VENDOR meshtastic_HardwareModel_SENSELORA_S3
|
||||
#elif defined(HELTEC_HT62)
|
||||
#define HW_VENDOR meshtastic_HardwareModel_HELTEC_HT62
|
||||
#elif defined(CHATTER_2)
|
||||
#define HW_VENDOR meshtastic_HardwareModel_CHATTER_2
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
@@ -175,7 +175,8 @@ void cpuDeepSleep(uint32_t msecToWake)
|
||||
some current will flow through these external and internal resistors, increasing deep
|
||||
sleep current above the minimal possible value.
|
||||
|
||||
Note: we don't isolate pins that are used for the LORA, LED, i2c, spi or the wake button
|
||||
Note: we don't isolate pins that are used for the LORA, LED, i2c, or ST7735 Display for the Chatter2, spi or the wake
|
||||
button(s), maybe we should not include any other GPIOs...
|
||||
*/
|
||||
#if SOC_RTCIO_HOLD_SUPPORTED
|
||||
static const uint8_t rtcGpios[] = {/* 0, */ 2,
|
||||
@@ -184,9 +185,9 @@ void cpuDeepSleep(uint32_t msecToWake)
|
||||
13,
|
||||
/* 14, */ /* 15, */
|
||||
#endif
|
||||
/* 25, */ 26, /* 27, */
|
||||
32, 33, 34, 35,
|
||||
36, 37
|
||||
/* 25, */ /* 26, */ /* 27, */
|
||||
/* 32, */ /* 33, */ 34, 35,
|
||||
/* 36, */ 37
|
||||
/* 38, 39 */};
|
||||
|
||||
for (int i = 0; i < sizeof(rtcGpios); i++)
|
||||
|
||||
@@ -81,6 +81,7 @@ void portduinoSetup()
|
||||
YAML::Node yamlConfig;
|
||||
|
||||
if (configPath != nullptr) {
|
||||
std::cout << "Using " << configPath << " as config file" << std::endl;
|
||||
try {
|
||||
yamlConfig = YAML::LoadFile(configPath);
|
||||
} catch (YAML::Exception e) {
|
||||
@@ -88,6 +89,7 @@ void portduinoSetup()
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
} else if (access("config.yaml", R_OK) == 0) {
|
||||
std::cout << "Using local config.yaml as config file" << std::endl;
|
||||
try {
|
||||
yamlConfig = YAML::LoadFile("config.yaml");
|
||||
} catch (YAML::Exception e) {
|
||||
@@ -95,6 +97,7 @@ void portduinoSetup()
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
} else if (access("/etc/meshtasticd/config.yaml", R_OK) == 0) {
|
||||
std::cout << "Using /etc/meshtasticd/config.yaml as config file" << std::endl;
|
||||
try {
|
||||
yamlConfig = YAML::LoadFile("/etc/meshtasticd/config.yaml");
|
||||
} catch (YAML::Exception e) {
|
||||
@@ -105,24 +108,21 @@ void portduinoSetup()
|
||||
std::cout << "No 'config.yaml' found, running simulated." << std::endl;
|
||||
// Set the random seed equal to TCPPort to have a different seed per instance
|
||||
randomSeed(TCPPort);
|
||||
|
||||
/* Aren't all pins defaulted to simulated?
|
||||
auto fakeBusy = new SimGPIOPin(SX126X_BUSY, "fakeBusy");
|
||||
fakeBusy->writePin(LOW);
|
||||
fakeBusy->setSilent(true);
|
||||
gpioBind(fakeBusy);
|
||||
|
||||
auto cs = new SimGPIOPin(SX126X_CS, "fakeLoraCS");
|
||||
cs->setSilent(true);
|
||||
gpioBind(cs);
|
||||
|
||||
gpioBind(new SimGPIOPin(SX126X_RESET, "fakeLoraReset"));
|
||||
gpioBind(new SimGPIOPin(LORA_DIO1, "fakeLoraIrq"));
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (yamlConfig["Logging"]) {
|
||||
if (yamlConfig["Logging"]["LogLevel"].as<std::string>("info") == "debug") {
|
||||
settingsMap[logoutputlevel] = level_debug;
|
||||
} else if (yamlConfig["Logging"]["LogLevel"].as<std::string>("info") == "info") {
|
||||
settingsMap[logoutputlevel] = level_info;
|
||||
} else if (yamlConfig["Logging"]["LogLevel"].as<std::string>("info") == "warn") {
|
||||
settingsMap[logoutputlevel] = level_warn;
|
||||
} else if (yamlConfig["Logging"]["LogLevel"].as<std::string>("info") == "error") {
|
||||
settingsMap[logoutputlevel] = level_error;
|
||||
}
|
||||
}
|
||||
if (yamlConfig["Lora"]) {
|
||||
settingsMap[use_sx1262] = false;
|
||||
settingsMap[use_rf95] = false;
|
||||
@@ -158,6 +158,9 @@ void portduinoSetup()
|
||||
settingsMap[has_gps] = 1;
|
||||
}
|
||||
}
|
||||
if (yamlConfig["I2C"]) {
|
||||
settingsStrings[i2cdev] = yamlConfig["I2C"]["I2CDevice"].as<std::string>("");
|
||||
}
|
||||
settingsMap[displayPanel] = no_screen;
|
||||
if (yamlConfig["Display"]) {
|
||||
if (yamlConfig["Display"]["Panel"].as<std::string>("") == "ST7789")
|
||||
|
||||
@@ -16,6 +16,7 @@ enum configNames {
|
||||
user,
|
||||
gpiochip,
|
||||
spidev,
|
||||
i2cdev,
|
||||
has_gps,
|
||||
touchscreenModule,
|
||||
touchscreenCS,
|
||||
@@ -31,10 +32,12 @@ enum configNames {
|
||||
displayOffsetX,
|
||||
displayOffsetY,
|
||||
displayInvert,
|
||||
keyboardDevice
|
||||
keyboardDevice,
|
||||
logoutputlevel
|
||||
};
|
||||
enum { no_screen, st7789, st7735, st7735s };
|
||||
enum { no_touchscreen, xpt2046 };
|
||||
enum { level_error, level_warn, level_info, level_debug };
|
||||
|
||||
extern std::map<configNames, int> settingsMap;
|
||||
extern std::map<configNames, std::string> settingsStrings;
|
||||
|
||||
13
variants/chatter2/platformio.ini
Normal file
13
variants/chatter2/platformio.ini
Normal file
@@ -0,0 +1,13 @@
|
||||
; CircuitMess Chatter 2 based on ESP32-WROOM-32 (38 pins) devkit & DeeamLNK DL-LLCC68 or Heltec HT RA62 SX1262/SX1268 module
|
||||
[env:chatter2]
|
||||
extends = esp32_base
|
||||
board = esp32doit-devkit-v1
|
||||
board_level = extra
|
||||
build_flags =
|
||||
${esp32_base.build_flags}
|
||||
-D CHATTER_2
|
||||
-I variants/chatter2
|
||||
|
||||
lib_deps =
|
||||
${esp32_base.lib_deps}
|
||||
lovyan03/LovyanGFX@^1.1.8
|
||||
118
variants/chatter2/variant.h
Normal file
118
variants/chatter2/variant.h
Normal file
@@ -0,0 +1,118 @@
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// Have custom connections or functionality? Configure them in this section //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Debugging
|
||||
// #define GPS_DEBUG
|
||||
// #define GPS_EXTRAVERBOSE
|
||||
|
||||
// Lora
|
||||
#define USE_LLCC68 // Original Chatter2 with LLCC68 module
|
||||
#define USE_SX1262 // Added for when Lora module is swapped for HT-RA62
|
||||
|
||||
#define SX126X_CS 14 // module's NSS pin
|
||||
#define LORA_SCK 16 // module's SCK pin
|
||||
#define LORA_MOSI 5 // module's MOSI pin
|
||||
#define LORA_MISO 17 // module's MISO pin
|
||||
#define SX126X_RESET RADIOLIB_NC // module's NRST pin
|
||||
#define SX126X_BUSY 4 // module's BUSY pin works for both LLCC68 and RA-62 with cut & jumper
|
||||
#define SX126X_DIO1 18 // module's DIO1 pin
|
||||
#define SX126X_DIO2_AS_RF_SWITCH // module's DIO2 pin
|
||||
#define SX126X_DIO3_TCXO_VOLTAGE 1.8 // module's DIO pin
|
||||
#define SX126X_TXEN RADIOLIB_NC
|
||||
#define SX126X_RXEN RADIOLIB_NC
|
||||
|
||||
// Status
|
||||
// #define LED_PIN 1
|
||||
// External notification
|
||||
// FIXME: Check if EXT_NOTIFY_OUT actualy has any effect and removes the need for setting the external notication pin in the
|
||||
// app/preferences
|
||||
// #define EXT_NOTIFY_OUT 2 // The GPIO pin that acts as the external notification output (here we connect an LED to it)
|
||||
|
||||
// Buzzer
|
||||
#define PIN_BUZZER 19
|
||||
// Buttons
|
||||
#define BUTTON_PIN 36 // Use the WAKE button as the user button
|
||||
// I2C
|
||||
// #define I2C_SCL 27
|
||||
// #define I2C_SDA 26
|
||||
|
||||
#define SX126X_MAX_POWER 22 // SX126xInterface.cpp defaults to 22 if not defined, but here we define it for good practice
|
||||
|
||||
// Display
|
||||
|
||||
#define HAS_SCREEN 1 // Assume no screen present by default to prevent crash...
|
||||
|
||||
// ST7735S TFT LCD
|
||||
#define ST7735S 1 // there are different (sub-)versions of ST7735
|
||||
#define ST7735_CS -1
|
||||
#define ST7735_RS 33 // DC
|
||||
#define ST7735_SDA 26 // MOSI
|
||||
#define ST7735_SCK 27
|
||||
#define ST7735_RESET 15
|
||||
#define ST7735_MISO -1
|
||||
#define ST7735_BUSY -1
|
||||
#define ST7735_BL 32
|
||||
#define ST7735_SPI_HOST HSPI_HOST // SPI2_HOST for S3, auto may work too
|
||||
#define SPI_FREQUENCY 40000000
|
||||
#define SPI_READ_FREQUENCY 16000000
|
||||
#define TFT_HEIGHT 160
|
||||
#define TFT_WIDTH 128
|
||||
#define TFT_OFFSET_X 0
|
||||
#define TFT_OFFSET_Y 0
|
||||
#define TFT_INVERT false
|
||||
#define SCREEN_ROTATE
|
||||
#define SCREEN_TRANSITION_FRAMERATE 5 // fps
|
||||
#define DISPLAY_FORCE_SMALL_FONTS
|
||||
|
||||
// Battery
|
||||
|
||||
#define BATTERY_PIN 34 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
|
||||
#define ADC_CHANNEL ADC1_GPIO34_CHANNEL
|
||||
#define ADC_ATTENUATION \
|
||||
ADC_ATTEN_DB_2_5 // 2_5-> 100mv-1250mv, 11-> 150mv-3100mv for ESP32
|
||||
// ESP32-S2/C3/S3 are different
|
||||
// lower dB for lower voltage rnage
|
||||
#define ADC_MULTIPLIER \
|
||||
5.0 // VBATT---10k--pin34---2.5K---GND
|
||||
// Chatter2 uses 3 AAA cells
|
||||
#define BAT_FULLVOLT 4800 // with the 5.0 divider, input to BATTERY_PIN is 900mv
|
||||
#define BAT_EMPTYVOLT 3300
|
||||
#undef EXT_PWR_DETECT
|
||||
|
||||
// GPS
|
||||
// FIXME: unsure what to define HAS_GPS as if GPS isn't always present
|
||||
#define HAS_GPS 1 // Don't need to set this to 0 to prevent a crash as it doesn't crash if GPS not found, will probe by default
|
||||
// #define PIN_GPS_EN 15
|
||||
// #define GPS_EN_ACTIVE 1
|
||||
#undef GPS_TX_PIN
|
||||
#undef GPS_RX_PIN
|
||||
#define GPS_TX_PIN 13
|
||||
#define GPS_RX_PIN 2
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// You should have no need to modify the code below, nor in pins_arduino.h //
|
||||
// //
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define LORA_CS SX126X_CS // FIXME: for some reason both are used in /src
|
||||
|
||||
// Many of the below values would only be used if USE_RF95 was defined, but it's not as we aren't actually using an RF95, just
|
||||
// that the 4 pins above are named like it If they aren't used they don't need to be defined and doing so cause confusion to those
|
||||
// adapting this file LORA_RESET value is never used in src (as we are not using RF95), so no need to define LORA_DIO0 is not used
|
||||
// in src (as we are not using RF95) as SX1262 does not have it per SX1262 datasheet, so no need to define
|
||||
// FIXME: confirm that the linked lines below are actually only called when using the SX126x or SX128x and no other modules
|
||||
// then use SX126X_DIO1 and SX128X_DIO1 respectively for that purpose, removing the need for RF95-style LORA_* definitions when
|
||||
// the RF95 isn't used
|
||||
#define LORA_DIO1 \
|
||||
SX126X_DIO1 // The old name is used in
|
||||
// https://github.com/meshtastic/firmware/blob/7eff5e7bcb2084499b723c5e3846c15ee089e36d/src/sleep.cpp#L298, so
|
||||
// must also define the old name
|
||||
// LORA_DIO2 value is never used in src (as we are not using RF95), so no need to define, and if DIO2_AS_RF_SWITCH is set then it
|
||||
// cannot serve any extra function even if requested to LORA_DIO3 value is never used in src (as we are not using RF95), so no
|
||||
// need to define, and DIO3_AS_TCXO_AT_1V8 is set so it cannot serve any extra function even if requested to (from 13.3.2.1
|
||||
// DioxMask in SX1262 datasheet: Note that if DIO2 or DIO3 are used to control the RF Switch or the TCXO, the IRQ will not be
|
||||
// generated even if it is mapped to the pins.)
|
||||
@@ -80,6 +80,7 @@ static const uint8_t A5 = PIN_A5;
|
||||
// Other pins
|
||||
#define PIN_AREF PIN_A5
|
||||
#define PIN_VBAT PIN_A4
|
||||
#define BATTERY_PIN PIN_VBAT
|
||||
#define PIN_NFC1 (33)
|
||||
#define PIN_NFC2 (2)
|
||||
#define PIN_PIEZO (37)
|
||||
|
||||
@@ -100,6 +100,7 @@ static const uint8_t A5 = PIN_A5;
|
||||
// Other pins
|
||||
#define PIN_AREF PIN_A5
|
||||
#define PIN_VBAT PIN_A4
|
||||
#define BATTERY_PIN PIN_VBAT
|
||||
#define PIN_NFC1 (33)
|
||||
#define PIN_NFC2 (2)
|
||||
#define PIN_PIEZO (37)
|
||||
|
||||
@@ -170,7 +170,7 @@ External serial flash W25Q16JV_IQ
|
||||
// Voltage divider value => 100K + 100K voltage divider on VBAT = (100K / (100K + 100K))
|
||||
#define VBAT_DIVIDER (0.5F)
|
||||
// Compensation factor for the VBAT divider
|
||||
#define VBAT_DIVIDER_COMP (2.0)
|
||||
#define VBAT_DIVIDER_COMP (2.0F)
|
||||
// Fixed calculation of milliVolt from compensation value
|
||||
#define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB)
|
||||
#undef AREF_VOLTAGE
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
#define HAS_WIRE 1
|
||||
#define HAS_SCREEN 1
|
||||
#define CANNED_MESSAGE_MODULE_ENABLE 1
|
||||
@@ -56,6 +56,8 @@ static const uint8_t SCK = 33;
|
||||
#define LED_PIN LED_BLUE
|
||||
|
||||
#define PIN_VBAT WB_A0
|
||||
#define BATTERY_PIN PIN_VBAT
|
||||
#define ADC_CHANNEL ADC1_GPIO36_CHANNEL
|
||||
|
||||
// https://docs.rakwireless.com/Product-Categories/WisBlock/RAK13300/
|
||||
|
||||
|
||||
@@ -10,4 +10,6 @@ build_flags = ${rp2040_base.build_flags}
|
||||
-DDEBUG_RP2040_PORT=Serial
|
||||
-L "${platformio.libdeps_dir}/${this.__env__}/BSEC2 Software Library/src/cortex-m0plus"
|
||||
lib_deps =
|
||||
${rp2040_base.lib_deps}
|
||||
${rp2040_base.lib_deps}
|
||||
debug_build_flags = ${rp2040_base.build_flags}
|
||||
debug_tool = cmsis-dap ; for e.g. Picotool
|
||||
@@ -12,6 +12,7 @@
|
||||
// #define EXT_NOTIFY_OUT 4
|
||||
|
||||
#define BATTERY_PIN 26
|
||||
#define BATTERY_SENSE_RESOLUTION_BITS ADC_RESOLUTION
|
||||
// ratio of voltage divider = 3.0 (R17=200k, R18=100k)
|
||||
#define ADC_MULTIPLIER 3.1 // 3.0 + a bit for being optimistic
|
||||
|
||||
|
||||
@@ -254,7 +254,7 @@ SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG
|
||||
// Voltage divider value => 1.5M + 1M voltage divider on VBAT = (1.5M / (1M + 1.5M))
|
||||
#define VBAT_DIVIDER (0.4F)
|
||||
// Compensation factor for the VBAT divider
|
||||
#define VBAT_DIVIDER_COMP (1.73)
|
||||
#define VBAT_DIVIDER_COMP (1.73F)
|
||||
// Fixed calculation of milliVolt from compensation value
|
||||
#define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB)
|
||||
#undef AREF_VOLTAGE
|
||||
|
||||
@@ -223,7 +223,7 @@ static const uint8_t SCK = PIN_SPI_SCK;
|
||||
// Voltage divider value => 1.5M + 1M voltage divider on VBAT = (1.5M / (1M + 1.5M))
|
||||
#define VBAT_DIVIDER (0.4F)
|
||||
// Compensation factor for the VBAT divider
|
||||
#define VBAT_DIVIDER_COMP (1.73)
|
||||
#define VBAT_DIVIDER_COMP (1.73F)
|
||||
// Fixed calculation of milliVolt from compensation value
|
||||
#define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB)
|
||||
#undef AREF_VOLTAGE
|
||||
|
||||
@@ -11,4 +11,6 @@ build_flags = ${rp2040_base.build_flags}
|
||||
-DHW_SPI1_DEVICE
|
||||
-L "${platformio.libdeps_dir}/${this.__env__}/BSEC2 Software Library/src/cortex-m0plus"
|
||||
lib_deps =
|
||||
${rp2040_base.lib_deps}
|
||||
${rp2040_base.lib_deps}
|
||||
debug_build_flags = ${rp2040_base.build_flags}
|
||||
debug_tool = cmsis-dap ; for e.g. Picotool
|
||||
@@ -22,6 +22,7 @@
|
||||
#define BATTERY_PIN 26
|
||||
// ratio of voltage divider = 3.0 (R17=200k, R18=100k)
|
||||
#define ADC_MULTIPLIER 3.1 // 3.0 + a bit for being optimistic
|
||||
#define BATTERY_SENSE_RESOLUTION_BITS ADC_RESOLUTION
|
||||
|
||||
#define USE_SX1262
|
||||
|
||||
|
||||
@@ -14,4 +14,6 @@ build_flags = ${rp2040_base.build_flags}
|
||||
build_src_filter = ${rp2040_base.build_src_filter} +<mesh/wifi/>
|
||||
lib_deps =
|
||||
${rp2040_base.lib_deps}
|
||||
${networking_base.lib_deps}
|
||||
${networking_base.lib_deps}
|
||||
debug_build_flags = ${rp2040_base.build_flags}
|
||||
debug_tool = cmsis-dap ; for e.g. Picotool
|
||||
@@ -24,6 +24,7 @@
|
||||
#define BATTERY_PIN 26
|
||||
// ratio of voltage divider = 3.0 (R17=200k, R18=100k)
|
||||
#define ADC_MULTIPLIER 3.1 // 3.0 + a bit for being optimistic
|
||||
#define BATTERY_SENSE_RESOLUTION_BITS ADC_RESOLUTION
|
||||
|
||||
#define USE_SX1262
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#define LED_PIN PIN_LED
|
||||
|
||||
#undef BATTERY_PIN
|
||||
#define BATTERY_SENSE_RESOLUTION_BITS ADC_RESOLUTION
|
||||
|
||||
#undef LORA_SCK
|
||||
#undef LORA_MISO
|
||||
|
||||
@@ -213,7 +213,7 @@ External serial flash WP25R1635FZUIL0
|
||||
// Voltage divider value => 100K + 100K voltage divider on VBAT = (100K / (100K + 100K))
|
||||
#define VBAT_DIVIDER (0.5F)
|
||||
// Compensation factor for the VBAT divider
|
||||
#define VBAT_DIVIDER_COMP (2.0)
|
||||
#define VBAT_DIVIDER_COMP (2.0F)
|
||||
// Fixed calculation of milliVolt from compensation value
|
||||
#define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB)
|
||||
#undef AREF_VOLTAGE
|
||||
|
||||
@@ -16,5 +16,13 @@
|
||||
#define USE_RF95
|
||||
#define LORA_DIO0 26 // a No connect on the SX1262 module
|
||||
#define LORA_RESET 23
|
||||
|
||||
// In the T3 V1.6.1 TXCO version, GPIO 33 is connected to Radio’s
|
||||
// internal temperature-compensated crystal oscillator enable
|
||||
#ifdef LORA_TCXO_GPIO
|
||||
#define LORA_DIO1 RADIOLIB_NC // no-connect on sx127x module
|
||||
#else
|
||||
#define LORA_DIO1 33 // https://www.thethingsnetwork.org/forum/t/big-esp32-sx127x-topic-part-3/18436
|
||||
#endif
|
||||
|
||||
#define LORA_DIO2 32 // Not really used
|
||||
9
variants/tlora_v2_1_16_tcxo/platformio.ini
Normal file
9
variants/tlora_v2_1_16_tcxo/platformio.ini
Normal file
@@ -0,0 +1,9 @@
|
||||
[env:tlora-v2-1-1_6-tcxo]
|
||||
extends = esp32_base
|
||||
board = ttgo-lora32-v21
|
||||
build_flags =
|
||||
${esp32_base.build_flags}
|
||||
-D TLORA_V2_1_16
|
||||
-I variants/tlora_v2_1_16
|
||||
-D GPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.
|
||||
-D LORA_TCXO_GPIO=33
|
||||
@@ -1,4 +1,4 @@
|
||||
[VERSION]
|
||||
major = 2
|
||||
minor = 2
|
||||
build = 19
|
||||
build = 21
|
||||
|
||||
Reference in New Issue
Block a user