mirror of
https://github.com/meshcore-dev/MeshCore.git
synced 2026-03-30 19:15:49 +00:00
Merge branch 'ripplebiz:dev' into dev
This commit is contained in:
@@ -46,7 +46,8 @@
|
||||
],
|
||||
"debug": {
|
||||
"jlink_device": "nRF52840_xxAA",
|
||||
"svd_path": "nrf52840.svd"
|
||||
"svd_path": "nrf52840.svd",
|
||||
"openocd_target": "nrf52.cfg"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino"
|
||||
@@ -69,4 +70,4 @@
|
||||
},
|
||||
"url": "https://wiki.uniteng.com/en/meshtastic/nano-g2-ultra",
|
||||
"vendor": "BQ Consulting"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "MyMesh.h"
|
||||
|
||||
#define AUTO_OFF_MILLIS 15000 // 15 seconds
|
||||
#define BOOT_SCREEN_MILLIS 4000 // 4 seconds
|
||||
#define BOOT_SCREEN_MILLIS 3000 // 3 seconds
|
||||
|
||||
#ifdef PIN_STATUS_LED
|
||||
#define LED_ON_MILLIS 20
|
||||
@@ -163,9 +163,9 @@ void UITask::renderCurrScreen() {
|
||||
|
||||
char tmp[80];
|
||||
if (_alert[0]) {
|
||||
_display->setTextSize(1.4);
|
||||
uint16_t textWidth = _display->getTextWidth(_alert);
|
||||
_display->setCursor((_display->width() - textWidth) / 2, 22);
|
||||
_display->setTextSize(1.4);
|
||||
_display->setColor(DisplayDriver::GREEN);
|
||||
_display->print(_alert);
|
||||
_alert[0] = 0;
|
||||
@@ -191,7 +191,7 @@ void UITask::renderCurrScreen() {
|
||||
sprintf(tmp, "%d", _msgcount);
|
||||
_display->print(tmp);
|
||||
_display->setColor(DisplayDriver::YELLOW); // last color will be kept on T114
|
||||
} else if (millis() < BOOT_SCREEN_MILLIS) { // boot screen
|
||||
} else if ((millis() - ui_started_at) < BOOT_SCREEN_MILLIS) { // boot screen
|
||||
// meshcore logo
|
||||
_display->setColor(DisplayDriver::BLUE);
|
||||
int logoWidth = 128;
|
||||
@@ -302,7 +302,7 @@ void UITask::loop() {
|
||||
|
||||
if (_display != NULL && _display->isOn()) {
|
||||
static bool _firstBoot = true;
|
||||
if(_firstBoot && millis() >= BOOT_SCREEN_MILLIS) {
|
||||
if(_firstBoot && (millis() - ui_started_at) >= BOOT_SCREEN_MILLIS) {
|
||||
_need_refresh = true;
|
||||
_firstBoot = false;
|
||||
}
|
||||
@@ -344,6 +344,8 @@ void UITask::handleButtonShortPress() {
|
||||
// Otherwise, refresh the display
|
||||
_need_refresh = true;
|
||||
}
|
||||
} else {
|
||||
_need_refresh = true; // display just turned on, so we need to refresh
|
||||
}
|
||||
// Note: Display turn-on and auto-off timer extension are handled by handleButtonAnyPress
|
||||
}
|
||||
@@ -372,10 +374,12 @@ void UITask::handleButtonTriplePress() {
|
||||
if (buzzer.isQuiet()) {
|
||||
buzzer.quiet(false);
|
||||
soundBuzzer(UIEventType::ack);
|
||||
sprintf(_alert, "Buzzer: ON");
|
||||
} else {
|
||||
soundBuzzer(UIEventType::ack);
|
||||
buzzer.quiet(true);
|
||||
sprintf(_alert, "Buzzer: OFF");
|
||||
}
|
||||
_need_refresh = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -337,6 +337,9 @@ protected:
|
||||
int getInterferenceThreshold() const override {
|
||||
return _prefs.interference_threshold;
|
||||
}
|
||||
int getAGCResetInterval() const override {
|
||||
return ((int)_prefs.agc_reset_interval) * 4000; // milliseconds
|
||||
}
|
||||
|
||||
void onAnonDataRecv(mesh::Packet* packet, uint8_t type, const mesh::Identity& sender, uint8_t* data, size_t len) override {
|
||||
if (type == PAYLOAD_TYPE_ANON_REQ) { // received an initial request by a possible admin client (unknown at this stage)
|
||||
@@ -575,7 +578,7 @@ public:
|
||||
_prefs.advert_interval = 1; // default to 2 minutes for NEW installs
|
||||
_prefs.flood_advert_interval = 3; // 3 hours
|
||||
_prefs.flood_max = 64;
|
||||
_prefs.interference_threshold = 14; // DB
|
||||
_prefs.interference_threshold = 0; // disabled
|
||||
}
|
||||
|
||||
CommonCLI* getCLI() { return &_cli; }
|
||||
|
||||
@@ -420,6 +420,9 @@ protected:
|
||||
int getInterferenceThreshold() const override {
|
||||
return _prefs.interference_threshold;
|
||||
}
|
||||
int getAGCResetInterval() const override {
|
||||
return ((int)_prefs.agc_reset_interval) * 4000; // milliseconds
|
||||
}
|
||||
|
||||
bool allowPacketForward(const mesh::Packet* packet) override {
|
||||
if (_prefs.disable_fwd) return false;
|
||||
@@ -725,7 +728,7 @@ public:
|
||||
_prefs.advert_interval = 1; // default to 2 minutes for NEW installs
|
||||
_prefs.flood_advert_interval = 3; // 3 hours
|
||||
_prefs.flood_max = 64;
|
||||
_prefs.interference_threshold = 14; // DB
|
||||
_prefs.interference_threshold = 0; // disabled
|
||||
#ifdef ROOM_PASSWORD
|
||||
StrHelper::strncpy(_prefs.guest_password, ROOM_PASSWORD, sizeof(_prefs.guest_password));
|
||||
#endif
|
||||
|
||||
@@ -87,6 +87,14 @@ void Dispatcher::loop() {
|
||||
} else {
|
||||
return; // can't do any more radio activity until send is complete or timed out
|
||||
}
|
||||
|
||||
// going back into receive mode now...
|
||||
next_agc_reset_time = futureMillis(getAGCResetInterval());
|
||||
}
|
||||
|
||||
if (getAGCResetInterval() > 0 && millisHasNowPassed(next_agc_reset_time)) {
|
||||
_radio->resetAGC();
|
||||
next_agc_reset_time = futureMillis(getAGCResetInterval());
|
||||
}
|
||||
|
||||
// check inbound (delayed) queue
|
||||
|
||||
@@ -65,6 +65,8 @@ public:
|
||||
|
||||
virtual void triggerNoiseFloorCalibrate(int threshold) { }
|
||||
|
||||
virtual void resetAGC() { }
|
||||
|
||||
virtual bool isInRecvMode() const = 0;
|
||||
|
||||
/**
|
||||
@@ -116,7 +118,7 @@ class Dispatcher {
|
||||
unsigned long next_tx_time;
|
||||
unsigned long cad_busy_start;
|
||||
unsigned long radio_nonrx_start;
|
||||
unsigned long next_floor_calib_time;
|
||||
unsigned long next_floor_calib_time, next_agc_reset_time;
|
||||
bool prev_isrecv_mode;
|
||||
uint32_t n_sent_flood, n_sent_direct;
|
||||
uint32_t n_recv_flood, n_recv_direct;
|
||||
@@ -134,7 +136,7 @@ protected:
|
||||
{
|
||||
outbound = NULL; total_air_time = 0; next_tx_time = 0;
|
||||
cad_busy_start = 0;
|
||||
next_floor_calib_time = 0;
|
||||
next_floor_calib_time = next_agc_reset_time = 0;
|
||||
_err_flags = 0;
|
||||
radio_nonrx_start = 0;
|
||||
prev_isrecv_mode = true;
|
||||
@@ -154,6 +156,7 @@ protected:
|
||||
virtual uint32_t getCADFailRetryDelay() const;
|
||||
virtual uint32_t getCADFailMaxDuration() const;
|
||||
virtual int getInterferenceThreshold() const { return 0; } // disabled by default
|
||||
virtual int getAGCResetInterval() const { return 0; } // disabled by default
|
||||
|
||||
public:
|
||||
void begin();
|
||||
|
||||
@@ -53,7 +53,8 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) {
|
||||
file.read((uint8_t *) &_prefs->allow_read_only, sizeof(_prefs->allow_read_only)); // 114
|
||||
file.read((uint8_t *) &_prefs->reserved2, sizeof(_prefs->reserved2)); // 115
|
||||
file.read((uint8_t *) &_prefs->bw, sizeof(_prefs->bw)); // 116
|
||||
file.read(pad, 4); // 120
|
||||
file.read((uint8_t *) &_prefs->agc_reset_interval, sizeof(_prefs->agc_reset_interval)); // 120
|
||||
file.read(pad, 3); // 121
|
||||
file.read((uint8_t *) &_prefs->flood_max, sizeof(_prefs->flood_max)); // 124
|
||||
file.read((uint8_t *) &_prefs->flood_advert_interval, sizeof(_prefs->flood_advert_interval)); // 125
|
||||
file.read((uint8_t *) &_prefs->interference_threshold, sizeof(_prefs->interference_threshold)); // 126
|
||||
@@ -107,7 +108,8 @@ void CommonCLI::savePrefs(FILESYSTEM* fs) {
|
||||
file.write((uint8_t *) &_prefs->allow_read_only, sizeof(_prefs->allow_read_only)); // 114
|
||||
file.write((uint8_t *) &_prefs->reserved2, sizeof(_prefs->reserved2)); // 115
|
||||
file.write((uint8_t *) &_prefs->bw, sizeof(_prefs->bw)); // 116
|
||||
file.write(pad, 4); // 120
|
||||
file.write((uint8_t *) &_prefs->agc_reset_interval, sizeof(_prefs->agc_reset_interval)); // 120
|
||||
file.write(pad, 3); // 121
|
||||
file.write((uint8_t *) &_prefs->flood_max, sizeof(_prefs->flood_max)); // 124
|
||||
file.write((uint8_t *) &_prefs->flood_advert_interval, sizeof(_prefs->flood_advert_interval)); // 125
|
||||
file.write((uint8_t *) &_prefs->interference_threshold, sizeof(_prefs->interference_threshold)); // 126
|
||||
@@ -180,6 +182,8 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
|
||||
sprintf(reply, "> %s", StrHelper::ftoa(_prefs->airtime_factor));
|
||||
} else if (memcmp(config, "int.thresh", 10) == 0) {
|
||||
sprintf(reply, "> %d", (uint32_t) _prefs->interference_threshold);
|
||||
} else if (memcmp(config, "agc.reset.interval", 18) == 0) {
|
||||
sprintf(reply, "> %d", ((uint32_t) _prefs->agc_reset_interval) * 4);
|
||||
} else if (memcmp(config, "allow.read.only", 15) == 0) {
|
||||
sprintf(reply, "> %s", _prefs->allow_read_only ? "on" : "off");
|
||||
} else if (memcmp(config, "flood.advert.interval", 21) == 0) {
|
||||
@@ -231,6 +235,10 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
|
||||
_prefs->interference_threshold = atoi(&config[11]);
|
||||
savePrefs();
|
||||
strcpy(reply, "OK");
|
||||
} else if (memcmp(config, "agc.reset.interval ", 19) == 0) {
|
||||
_prefs->agc_reset_interval = atoi(&config[19]) / 4;
|
||||
savePrefs();
|
||||
strcpy(reply, "OK");
|
||||
} else if (memcmp(config, "allow.read.only ", 16) == 0) {
|
||||
_prefs->allow_read_only = memcmp(&config[16], "on", 2) == 0;
|
||||
savePrefs();
|
||||
|
||||
@@ -25,6 +25,7 @@ struct NodePrefs { // persisted to file
|
||||
float bw;
|
||||
uint8_t flood_max;
|
||||
uint8_t interference_threshold;
|
||||
uint8_t agc_reset_interval; // secs / 4
|
||||
};
|
||||
|
||||
class CommonCLICallbacks {
|
||||
|
||||
@@ -52,6 +52,15 @@ void RadioLibWrapper::triggerNoiseFloorCalibrate(int threshold) {
|
||||
}
|
||||
}
|
||||
|
||||
void RadioLibWrapper::resetAGC() {
|
||||
// make sure we're not mid-receive of packet!
|
||||
if ((state & STATE_INT_READY) != 0 || isReceivingPacket()) return;
|
||||
|
||||
// NOTE: according to higher powers, just issuing RadioLib's startReceive() will reset the AGC.
|
||||
// revisit this if a better impl is discovered.
|
||||
state = STATE_IDLE; // trigger a startReceive()
|
||||
}
|
||||
|
||||
void RadioLibWrapper::loop() {
|
||||
if (state == STATE_RX && _num_floor_samples < NUM_NOISE_FLOOR_SAMPLES) {
|
||||
if (!isReceivingPacket()) {
|
||||
|
||||
@@ -39,6 +39,7 @@ public:
|
||||
|
||||
int getNoiseFloor() const override { return _noise_floor; }
|
||||
void triggerNoiseFloorCalibrate(int threshold) override;
|
||||
void resetAGC() override;
|
||||
|
||||
void loop() override;
|
||||
|
||||
|
||||
@@ -26,6 +26,11 @@ void ThinkNodeM1Board::begin() {
|
||||
|
||||
Wire.begin();
|
||||
|
||||
#ifdef P_LORA_TX_LED
|
||||
pinMode(P_LORA_TX_LED, OUTPUT);
|
||||
digitalWrite(P_LORA_TX_LED, LOW);
|
||||
#endif
|
||||
|
||||
pinMode(SX126X_POWER_EN, OUTPUT);
|
||||
digitalWrite(SX126X_POWER_EN, HIGH);
|
||||
delay(10); // give sx1262 some time to power up
|
||||
|
||||
@@ -39,6 +39,15 @@ public:
|
||||
return startup_reason;
|
||||
}
|
||||
|
||||
#if defined(P_LORA_TX_LED)
|
||||
void onBeforeTransmit() override {
|
||||
digitalWrite(P_LORA_TX_LED, HIGH); // turn TX LED on
|
||||
}
|
||||
void onAfterTransmit() override {
|
||||
digitalWrite(P_LORA_TX_LED, LOW); // turn TX LED off
|
||||
}
|
||||
#endif
|
||||
|
||||
const char* getManufacturerName() const override {
|
||||
return "Elecrow ThinkNode-M1";
|
||||
}
|
||||
|
||||
33
variants/heltec_ct62/HT-CT62Board.h
Normal file
33
variants/heltec_ct62/HT-CT62Board.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <MeshCore.h>
|
||||
#include <Arduino.h>
|
||||
|
||||
#if defined(ESP_PLATFORM)
|
||||
|
||||
#include <helpers/ESP32Board.h>
|
||||
|
||||
class Heltec_CT62_Board : public ESP32Board {
|
||||
public:
|
||||
|
||||
uint16_t getBattMilliVolts() override {
|
||||
#ifdef PIN_VBAT_READ
|
||||
analogReadResolution(12); // ESP32-C3 ADC is 12-bit - 3.3/4096 (ref voltage/max counts)
|
||||
uint32_t raw = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
raw += analogRead(PIN_VBAT_READ);
|
||||
}
|
||||
raw = raw / 8;
|
||||
|
||||
return ((6.52 * raw) / 1024.0) * 1000;
|
||||
#else
|
||||
return 0; // not supported
|
||||
#endif
|
||||
}
|
||||
|
||||
const char* getManufacturerName() const override {
|
||||
return "Heltec CT62";
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -12,12 +12,13 @@ build_flags =
|
||||
-D P_LORA_TX_LED=18
|
||||
-D PIN_BOARD_SDA=0
|
||||
-D PIN_BOARD_SCL=1
|
||||
-D PIN_USER_BTN=9
|
||||
;-D PIN_USER_BTN=9
|
||||
-D PIN_VBAT_READ=2
|
||||
-D P_LORA_DIO_1=3
|
||||
-D P_LORA_NSS=8
|
||||
-D P_LORA_RESET=5
|
||||
-D P_LORA_RESET=RADIOLIB_NC
|
||||
-D P_LORA_DIO_0=RADIOLIB_NC
|
||||
-D P_LORA_DIO_2=RADIOLIB_NC
|
||||
-D P_LORA_BUSY=4
|
||||
-D P_LORA_SCLK=10
|
||||
-D P_LORA_MISO=6
|
||||
@@ -33,6 +34,8 @@ build_src_filter = ${esp32_base.build_src_filter}
|
||||
extends = Heltec_ct62
|
||||
build_flags =
|
||||
${Heltec_ct62.build_flags}
|
||||
;-D ARDUINO_USB_MODE=1
|
||||
;-D ARDUINO_USB_CDC_ON_BOOT=1
|
||||
-D ADVERT_NAME='"HT-CT62 Repeater"'
|
||||
-D ADVERT_LAT=0.0
|
||||
-D ADVERT_LON=0.0
|
||||
@@ -45,3 +48,41 @@ build_src_filter = ${Heltec_ct62.build_src_filter}
|
||||
lib_deps =
|
||||
${Heltec_ct62.lib_deps}
|
||||
${esp32_ota.lib_deps}
|
||||
|
||||
[env:Heltec_ct62_companion_radio_usb]
|
||||
extends = Heltec_ct62
|
||||
build_flags =
|
||||
${Heltec_ct62.build_flags}
|
||||
; -D ARDUINO_USB_MODE=1
|
||||
; -D ARDUINO_USB_CDC_ON_BOOT=1
|
||||
-D MAX_CONTACTS=100
|
||||
-D MAX_GROUP_CHANNELS=8
|
||||
-D OFFLINE_QUEUE_SIZE=256
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
build_src_filter = ${Heltec_ct62.build_src_filter}
|
||||
+<../examples/companion_radio>
|
||||
lib_deps =
|
||||
${Heltec_ct62.lib_deps}
|
||||
${esp32_ota.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
|
||||
[env:Heltec_ct62_companion_radio_ble]
|
||||
extends = Heltec_ct62
|
||||
build_flags =
|
||||
${Heltec_ct62.build_flags}
|
||||
; -D ARDUINO_USB_MODE=1
|
||||
; -D ARDUINO_USB_CDC_ON_BOOT=1
|
||||
-D MAX_CONTACTS=100
|
||||
-D MAX_GROUP_CHANNELS=8
|
||||
-D OFFLINE_QUEUE_SIZE=256
|
||||
-D BLE_PIN_CODE=123456
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
build_src_filter = ${Heltec_ct62.build_src_filter}
|
||||
+<../examples/companion_radio>
|
||||
+<helpers/esp32/SerialBLEInterface.cpp>
|
||||
lib_deps =
|
||||
${Heltec_ct62.lib_deps}
|
||||
${esp32_ota.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
|
||||
@@ -1,14 +1,9 @@
|
||||
#include <Arduino.h>
|
||||
#include "target.h"
|
||||
|
||||
ESP32Board board;
|
||||
|
||||
#if defined(P_LORA_SCLK)
|
||||
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY);
|
||||
#else
|
||||
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY);
|
||||
#endif
|
||||
Heltec_CT62_Board board;
|
||||
|
||||
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY);
|
||||
WRAPPER_CLASS radio_driver(radio, board);
|
||||
|
||||
ESP32RTCClock fallback_clock;
|
||||
@@ -72,4 +67,4 @@ void radio_set_tx_power(uint8_t dbm) {
|
||||
mesh::LocalIdentity radio_new_identity() {
|
||||
RadioNoiseListener rng(radio);
|
||||
return mesh::LocalIdentity(&rng); // create new random identity
|
||||
}
|
||||
}
|
||||
@@ -3,12 +3,12 @@
|
||||
#define RADIOLIB_STATIC_ONLY 1
|
||||
#include <RadioLib.h>
|
||||
#include <helpers/RadioLibWrappers.h>
|
||||
#include <helpers/ESP32Board.h>
|
||||
#include "HT-CT62Board.h"
|
||||
#include <helpers/CustomSX1262Wrapper.h>
|
||||
#include <helpers/AutoDiscoverRTCClock.h>
|
||||
#include <helpers/SensorManager.h>
|
||||
|
||||
extern ESP32Board board;
|
||||
extern Heltec_CT62_Board board;
|
||||
extern WRAPPER_CLASS radio_driver;
|
||||
extern AutoDiscoverRTCClock rtc_clock;
|
||||
extern SensorManager sensors;
|
||||
@@ -17,4 +17,4 @@ bool radio_init();
|
||||
uint32_t radio_get_rng_seed();
|
||||
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr);
|
||||
void radio_set_tx_power(uint8_t dbm);
|
||||
mesh::LocalIdentity radio_new_identity();
|
||||
mesh::LocalIdentity radio_new_identity();
|
||||
@@ -19,6 +19,7 @@ build_flags = ${nrf52840_thinknode_m1.build_flags}
|
||||
-D RADIO_CLASS=CustomSX1262
|
||||
-D WRAPPER_CLASS=CustomSX1262Wrapper
|
||||
-D LORA_TX_POWER=22
|
||||
-D P_LORA_TX_LED=13
|
||||
-D SX126X_CURRENT_LIMIT=140
|
||||
-D SX126X_RX_BOOSTED_GAIN=1
|
||||
build_src_filter = ${nrf52840_thinknode_m1.build_src_filter}
|
||||
|
||||
Reference in New Issue
Block a user