Skip to content

Commit c4dff21

Browse files
thebenternford-jonesWillyJLfifieldtQuency-D
authored
Develop -> Master (#8209)
* Create channel-mute toggle function * Added mute state to channel settings * Create node-mute toggle functions * Added mute state to nodedb entries * Rebase protos * Decouple protobuf changes * Disable bell-invoked ext notifs for muted nodes * Clearly dilineate module mute from sender or channel mute * Disable bell-invoked ext notifs for muted channels * Trunk fmt * Disable message-invoked ext notifs for muted channels and nodes * Disable on-screen 'new message' popup for muted nodes and channels * Don't mute alerts * Make use of pre-existing channel_settings.module_settings.is_client_muted setting * Revert previous commit - this needs it's own proto * Regen protos * T-Lora Pager: Interrupt based rotary encoder * T-Lora Pager: Fix amplifier fuzzing/popping * Fix build for other variants * Fix - reference actual channel when changing settings * Update protos * Refactor ref syntax * Fix defines * Update comments and remove unused function * Regen protos * Regen protobuffs again * Fix build failure in ci, add missing argument * Format * InputPollable: System for polling after interrupts * T-Lora Pager: Use InputPollable for RotaryEncoderImpl * Rename RotaryEncoderImpl to TLoraPagerRotaryEncoder * Revert "Rename RotaryEncoderImpl to TLoraPagerRotaryEncoder" This reverts commit a76cc88. * Revert unnecessary ifdefs * Regen protos * Use latest protos * Regen protos for latest changes * Decouple node-mute from channel-mute * Regen protos * Fix desktop build * More flexible InputPollable paradigm * Custom xPortInIsrContext() for nRF52/RP2xx0 * Use channel as specified in the received packet * Use channel as specified in the received packet for OLED screen notifications * add heltec tracker v2 board. * Use common power amp definition for Heltec v4 and Heltec Tracker v2 * Set appropriate mqtt root upon lora region change * Use user preferences root topic if present * delete SX126X_MAX_POWER=11 * Assume previous root on topic change * update mqtt root when region is changed via OLED menu handler * Regen protos * Removed magic numbers * Add DIRECT_MSG_ONLY buzzer mode (#8158) * Handle existing special case for M5STACK_UNITC6L for DIRECT_MSG_ONLY buzz mode There already exists a special case for M5STACK_UNITC6L. Modified it to adhere to new DIRECT_MSG_ONLY buzzer mode * Add new buzzer mode DIRECT_MSG_ONLY to BuzzerModeMenu * Disable notifications when buzzer mode is DIRECT_MSG_ONLY * Change alert_message_buzzer in notification module in DIRECT_MSG_ONLY buzz mode Better comments * Fixed spelling in debug log Co-authored-by: Copilot <[email protected]> --------- Co-authored-by: nexpspace <[email protected]> Co-authored-by: Copilot <[email protected]> Co-authored-by: Ben Meadors <[email protected]> * run trunk fmt * Update variants/esp32s3/heltec_wireless_tracker_v2/variant.h Co-authored-by: Copilot <[email protected]> * Regen protos * Pull latest protobufs * Don't use IS_ONE_OF when loading Modules * GAT562: Use PRIVATE_HW (fix build) (#8198) * ESP32s2 doesn't implement HWCDC (#8199) * Fix build script failure under certain conditions for devices that use UF2 binaries (#8150) * Validate CR and SF lora config (#8146) * Validate CR and SF lora config * No zero-bw * Update src/modules/AdminModule.cpp Co-authored-by: Copilot <[email protected]> * Fix braces --------- Co-authored-by: Copilot <[email protected]> * Quote firmware paths given to uf2conv --------- Co-authored-by: Ben Meadors <[email protected]> Co-authored-by: Copilot <[email protected]> * Calculate airtime of transmitted and received packets separately (#8205) * Correcting GPS PINs (#8087) #8084 Co-authored-by: Ben Meadors <[email protected]> * Clear out user.id except for sending to phone (#8202) * Null out user.id except for sending to phone * Fix * Update src/modules/NodeInfoModule.cpp Co-authored-by: Copilot <[email protected]> * Copilot garbage * This is unnecessary, because we don't stored user.id on userlite * Don't need this * Fix warning * Just alter the protobuf * Alter protobuf doesn't do anything with the altered data, so let's re-encode it * Check inputbroker before access --------- Co-authored-by: Copilot <[email protected]> * Add dropped packet count to LocalStats (#8207) * Add dropped packet count to LocalStats In case the transmit queue was full * Trunked --------- Co-authored-by: Ben Meadors <[email protected]> --------- Co-authored-by: ford-jones <[email protected]> Co-authored-by: WillyJL <[email protected]> Co-authored-by: Ford Jones <[email protected]> Co-authored-by: Tom Fifield <[email protected]> Co-authored-by: Quency-D <[email protected]> Co-authored-by: Quency-D <[email protected]> Co-authored-by: nexpspace <[email protected]> Co-authored-by: nexpspace <[email protected]> Co-authored-by: Copilot <[email protected]> Co-authored-by: Austin Lane <[email protected]> Co-authored-by: Ken Piper <[email protected]> Co-authored-by: GUVWAF <[email protected]> Co-authored-by: Szetya <[email protected]>
2 parents ed32650 + 888692a commit c4dff21

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+616
-161
lines changed

bin/platformio-custom.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ def esp32_create_combined_bin(source, target, env):
8686

8787
if platform.name == "nordicnrf52":
8888
env.AddPostAction("$BUILD_DIR/${PROGNAME}.hex",
89-
env.VerboseAction(f"\"{sys.executable}\" ./bin/uf2conv.py $BUILD_DIR/firmware.hex -c -f 0xADA52840 -o $BUILD_DIR/firmware.uf2",
89+
env.VerboseAction(f"\"{sys.executable}\" ./bin/uf2conv.py \"$BUILD_DIR/firmware.hex\" -c -f 0xADA52840 -o \"$BUILD_DIR/firmware.uf2\"",
9090
"Generating UF2 file"))
9191

9292
Import("projenv")
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"build": {
3+
"arduino": {
4+
"ldscript": "esp32s3_out.ld",
5+
"partitions": "default_8MB.csv"
6+
},
7+
"core": "esp32",
8+
"extra_flags": [
9+
"-DARDUINO_USB_CDC_ON_BOOT=1",
10+
"-DARDUINO_USB_MODE=0",
11+
"-DARDUINO_RUNNING_CORE=1",
12+
"-DARDUINO_EVENT_RUNNING_CORE=1"
13+
],
14+
"f_cpu": "240000000L",
15+
"f_flash": "80000000L",
16+
"flash_mode": "qio",
17+
"hwids": [["0x303A", "0x1001"]],
18+
"mcu": "esp32s3",
19+
"variant": "heltec_wireless_tracker_v2"
20+
},
21+
"connectivity": ["wifi", "bluetooth", "lora"],
22+
"debug": {
23+
"openocd_target": "esp32s3.cfg"
24+
},
25+
"frameworks": ["arduino", "espidf"],
26+
"name": "Heltec Wireless Tracker V2",
27+
"upload": {
28+
"flash_size": "8MB",
29+
"maximum_ram_size": 327680,
30+
"maximum_size": 8388608,
31+
"wait_for_upload_port": true,
32+
"require_upload_port": true,
33+
"speed": 921600
34+
},
35+
"url": "https://heltec.org",
36+
"vendor": "Heltec"
37+
}

src/AudioThread.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@
1111
#include <AudioOutputI2S.h>
1212
#include <ESP8266SAM.h>
1313

14+
#ifdef USE_XL9555
15+
#include "ExtensionIOXL9555.hpp"
16+
extern ExtensionIOXL9555 io;
17+
#endif
18+
1419
#define AUDIO_THREAD_INTERVAL_MS 100
1520

1621
class AudioThread : public concurrency::OSThread
@@ -20,6 +25,9 @@ class AudioThread : public concurrency::OSThread
2025

2126
void beginRttl(const void *data, uint32_t len)
2227
{
28+
#ifdef T_LORA_PAGER
29+
io.digitalWrite(EXPANDS_AMP_EN, HIGH);
30+
#endif
2331
setCPUFast(true);
2432
rtttlFile = new AudioFileSourcePROGMEM(data, len);
2533
i2sRtttl = new AudioGeneratorRTTTL();
@@ -46,6 +54,9 @@ class AudioThread : public concurrency::OSThread
4654
rtttlFile = nullptr;
4755

4856
setCPUFast(false);
57+
#ifdef T_LORA_PAGER
58+
io.digitalWrite(EXPANDS_AMP_EN, LOW);
59+
#endif
4960
}
5061

5162
void readAloud(const char *text)
@@ -56,10 +67,16 @@ class AudioThread : public concurrency::OSThread
5667
i2sRtttl = nullptr;
5768
}
5869

70+
#ifdef T_LORA_PAGER
71+
io.digitalWrite(EXPANDS_AMP_EN, HIGH);
72+
#endif
5973
ESP8266SAM *sam = new ESP8266SAM;
6074
sam->Say(audioOut, text);
6175
delete sam;
6276
setCPUFast(false);
77+
#ifdef T_LORA_PAGER
78+
io.digitalWrite(EXPANDS_AMP_EN, LOW);
79+
#endif
6380
}
6481

6582
protected:

src/SerialConsole.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ int32_t SerialConsole::runOnce()
8686
#endif
8787

8888
int32_t delay = runOncePart();
89-
#if defined(SERIAL_HAS_ON_RECEIVE)
89+
#if defined(SERIAL_HAS_ON_RECEIVE) || defined(CONFIG_IDF_TARGET_ESP32S2)
9090
return Port.available() ? delay : INT32_MAX;
9191
#elif defined(IS_USB_SERIAL)
9292
return HWCDC::isPlugged() ? delay : (1000 * 20);

src/buzz/BuzzerFeedbackThread.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ int BuzzerFeedbackThread::handleInputEvent(const InputEvent *event)
1515
{
1616
// Only provide feedback if buzzer is enabled for notifications
1717
if (config.device.buzzer_mode == meshtastic_Config_DeviceConfig_BuzzerMode_DISABLED ||
18-
config.device.buzzer_mode == meshtastic_Config_DeviceConfig_BuzzerMode_NOTIFICATIONS_ONLY) {
18+
config.device.buzzer_mode == meshtastic_Config_DeviceConfig_BuzzerMode_NOTIFICATIONS_ONLY ||
19+
config.device.buzzer_mode == meshtastic_Config_DeviceConfig_BuzzerMode_DIRECT_MSG_ONLY) {
1920
return 0; // Let other handlers process the event
2021
}
2122

src/configuration.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
117117
#define SX126X_MAX_POWER 22
118118
#endif
119119

120-
#ifdef HELTEC_V4
120+
#ifdef USE_GC1109_PA
121121
// Power Amps are often non-linear, so we can use an array of values for the power curve
122122
#define NUM_PA_POINTS 22
123123
#define TX_GAIN_LORA 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 9, 9, 8, 7

src/graphics/Screen.cpp

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ namespace graphics
100100
#define NUM_EXTRA_FRAMES 3 // text message and debug frame
101101
// if defined a pixel will blink to show redraws
102102
// #define SHOW_REDRAWS
103-
103+
#define ASCII_BELL '\x07'
104104
// A text message frame + debug frame + all the node infos
105105
FrameCallback *normalFrames;
106106
static uint32_t targetFramerate = IDLE_FRAMERATE;
@@ -453,7 +453,7 @@ void Screen::handleSetOn(bool on, FrameCallback einkScreensaver)
453453
#endif
454454

455455
dispdev->displayOn();
456-
#ifdef HELTEC_TRACKER_V1_X
456+
#if defined(HELTEC_TRACKER_V1_X) || defined(HELTEC_WIRELESS_TRACKER_V2)
457457
ui->init();
458458
#endif
459459
#ifdef USE_ST7789
@@ -1458,28 +1458,36 @@ int Screen::handleTextMessage(const meshtastic_MeshPacket *packet)
14581458
}
14591459
// === Prepare banner content ===
14601460
const meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(packet->from);
1461+
const meshtastic_Channel channel =
1462+
channels.getByIndex(packet->channel ? packet->channel : channels.getPrimaryIndex());
14611463
const char *longName = (node && node->has_user) ? node->user.long_name : nullptr;
14621464

14631465
const char *msgRaw = reinterpret_cast<const char *>(packet->decoded.payload.bytes);
14641466

14651467
char banner[256];
14661468

1467-
// Check for bell character in message to determine alert type
14681469
bool isAlert = false;
1469-
for (size_t i = 0; i < packet->decoded.payload.size && i < 100; i++) {
1470-
if (msgRaw[i] == '\x07') {
1471-
isAlert = true;
1472-
break;
1470+
1471+
if (moduleConfig.external_notification.alert_bell || moduleConfig.external_notification.alert_bell_vibra ||
1472+
moduleConfig.external_notification.alert_bell_buzzer)
1473+
// Check for bell character to determine if this message is an alert
1474+
for (size_t i = 0; i < packet->decoded.payload.size && i < 100; i++) {
1475+
if (msgRaw[i] == ASCII_BELL) {
1476+
isAlert = true;
1477+
break;
1478+
}
14731479
}
1474-
}
14751480

1481+
// Unlike generic messages, alerts (when enabled via the ext notif module) ignore any
1482+
// 'mute' preferences set to any specific node or channel.
14761483
if (isAlert) {
14771484
if (longName && longName[0]) {
14781485
snprintf(banner, sizeof(banner), "Alert Received from\n%s", longName);
14791486
} else {
14801487
strcpy(banner, "Alert Received");
14811488
}
1482-
} else {
1489+
screen->showSimpleBanner(banner, 3000);
1490+
} else if (!channel.settings.mute) {
14831491
if (longName && longName[0]) {
14841492
#if defined(M5STACK_UNITC6L)
14851493
strcpy(banner, "New Message");
@@ -1490,14 +1498,21 @@ int Screen::handleTextMessage(const meshtastic_MeshPacket *packet)
14901498
} else {
14911499
strcpy(banner, "New Message");
14921500
}
1493-
}
14941501
#if defined(M5STACK_UNITC6L)
1495-
screen->setOn(true);
1496-
screen->showSimpleBanner(banner, 1500);
1497-
playLongBeep();
1502+
screen->setOn(true);
1503+
screen->showSimpleBanner(banner, 1500);
1504+
if (config.device.buzzer_mode != meshtastic_Config_DeviceConfig_BuzzerMode_DIRECT_MSG_ONLY ||
1505+
(isAlert && moduleConfig.external_notification.alert_bell_buzzer) ||
1506+
(!isBroadcast(packet->to) && isToUs(p))) {
1507+
// Beep if not in DIRECT_MSG_ONLY mode or if in DIRECT_MSG_ONLY mode and either
1508+
// - packet contains an alert and alert bell buzzer is enabled
1509+
// - packet is a non-broadcast that is addressed to this node
1510+
playLongBeep();
1511+
}
14981512
#else
1499-
screen->showSimpleBanner(banner, 3000);
1513+
screen->showSimpleBanner(banner, 3000);
15001514
#endif
1515+
}
15011516
}
15021517
}
15031518

src/graphics/draw/MenuHandler.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ void menuHandler::LoraRegionPicker(uint32_t duration)
116116
bannerOptions.bannerCallback = [](int selected) -> void {
117117
if (selected != 0 && config.lora.region != _meshtastic_Config_LoRaConfig_RegionCode(selected)) {
118118
config.lora.region = _meshtastic_Config_LoRaConfig_RegionCode(selected);
119+
auto changes = SEGMENT_CONFIG;
120+
119121
// This is needed as we wait til picking the LoRa region to generate keys for the first time.
120122
if (!owner.is_licensed) {
121123
bool keygenSuccess = false;
@@ -124,6 +126,7 @@ void menuHandler::LoraRegionPicker(uint32_t duration)
124126
if (crypto->regeneratePublicKey(config.security.public_key.bytes, config.security.private_key.bytes)) {
125127
keygenSuccess = true;
126128
}
129+
127130
} else {
128131
LOG_INFO("Generate new PKI keys");
129132
crypto->generateKeyPair(config.security.public_key.bytes, config.security.private_key.bytes);
@@ -141,7 +144,14 @@ void menuHandler::LoraRegionPicker(uint32_t duration)
141144
if (myRegion->dutyCycle < 100) {
142145
config.lora.ignore_mqtt = true; // Ignore MQTT by default if region has a duty cycle limit
143146
}
144-
service->reloadConfig(SEGMENT_CONFIG);
147+
148+
if (strncmp(moduleConfig.mqtt.root, default_mqtt_root, strlen(default_mqtt_root)) == 0) {
149+
// Default broker is in use, so subscribe to the appropriate MQTT root topic for this region
150+
sprintf(moduleConfig.mqtt.root, "%s/%s", default_mqtt_root, myRegion->name);
151+
changes |= SEGMENT_MODULECONFIG;
152+
}
153+
154+
service->reloadConfig(changes);
145155
rebootAtMsec = (millis() + DEFAULT_REBOOT_SECONDS * 1000);
146156
}
147157
};
@@ -911,11 +921,11 @@ void menuHandler::BluetoothToggleMenu()
911921

912922
void menuHandler::BuzzerModeMenu()
913923
{
914-
static const char *optionsArray[] = {"All Enabled", "Disabled", "Notifications", "System Only"};
924+
static const char *optionsArray[] = {"All Enabled", "Disabled", "Notifications", "System Only", "DMs Only"};
915925
BannerOverlayOptions bannerOptions;
916926
bannerOptions.message = "Buzzer Mode";
917927
bannerOptions.optionsArrayPtr = optionsArray;
918-
bannerOptions.optionsCount = 4;
928+
bannerOptions.optionsCount = 5;
919929
bannerOptions.bannerCallback = [](int selected) -> void {
920930
config.device.buzzer_mode = (meshtastic_Config_DeviceConfig_BuzzerMode)selected;
921931
service->reloadConfig(SEGMENT_CONFIG);

src/input/InputBroker.cpp

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,66 @@
33

44
InputBroker *inputBroker = nullptr;
55

6-
InputBroker::InputBroker(){};
6+
InputBroker::InputBroker()
7+
{
8+
#ifdef HAS_FREE_RTOS
9+
inputEventQueue = xQueueCreate(5, sizeof(InputEvent));
10+
pollSoonQueue = xQueueCreate(5, sizeof(InputPollable *));
11+
xTaskCreate(pollSoonWorker, "input-pollSoon", 2 * 1024, this, 10, &pollSoonTask);
12+
#endif
13+
}
714

815
void InputBroker::registerSource(Observable<const InputEvent *> *source)
916
{
1017
this->inputEventObserver.observe(source);
1118
}
1219

20+
#ifdef HAS_FREE_RTOS
21+
void InputBroker::requestPollSoon(InputPollable *pollable)
22+
{
23+
if (xPortInIsrContext() == pdTRUE) {
24+
xQueueSendFromISR(pollSoonQueue, &pollable, NULL);
25+
} else {
26+
xQueueSend(pollSoonQueue, &pollable, 0);
27+
}
28+
}
29+
30+
void InputBroker::queueInputEvent(const InputEvent *event)
31+
{
32+
if (xPortInIsrContext() == pdTRUE) {
33+
xQueueSendFromISR(inputEventQueue, event, NULL);
34+
} else {
35+
xQueueSend(inputEventQueue, event, portMAX_DELAY);
36+
}
37+
}
38+
39+
void InputBroker::processInputEventQueue()
40+
{
41+
InputEvent event;
42+
while (xQueueReceive(inputEventQueue, &event, 0)) {
43+
handleInputEvent(&event);
44+
}
45+
}
46+
#endif
47+
1348
int InputBroker::handleInputEvent(const InputEvent *event)
1449
{
1550
powerFSM.trigger(EVENT_INPUT); // todo: not every input should wake, like long hold release
1651
this->notifyObservers(event);
1752
return 0;
18-
}
53+
}
54+
55+
#ifdef HAS_FREE_RTOS
56+
void InputBroker::pollSoonWorker(void *p)
57+
{
58+
InputBroker *instance = (InputBroker *)p;
59+
while (true) {
60+
InputPollable *pollable = NULL;
61+
xQueueReceive(instance->pollSoonQueue, &pollable, portMAX_DELAY);
62+
if (pollable) {
63+
pollable->pollOnce();
64+
}
65+
}
66+
vTaskDelete(NULL);
67+
}
68+
#endif

src/input/InputBroker.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#pragma once
2+
23
#include "Observer.h"
4+
#include "freertosinc.h"
35

46
enum input_broker_event {
57
INPUT_BROKER_NONE = 0,
@@ -41,6 +43,13 @@ typedef struct _InputEvent {
4143
uint16_t touchX;
4244
uint16_t touchY;
4345
} InputEvent;
46+
47+
class InputPollable
48+
{
49+
public:
50+
virtual void pollOnce() = 0;
51+
};
52+
4453
class InputBroker : public Observable<const InputEvent *>
4554
{
4655
CallbackObserver<InputBroker, const InputEvent *> inputEventObserver =
@@ -50,9 +59,22 @@ class InputBroker : public Observable<const InputEvent *>
5059
InputBroker();
5160
void registerSource(Observable<const InputEvent *> *source);
5261
void injectInputEvent(const InputEvent *event) { handleInputEvent(event); }
62+
#ifdef HAS_FREE_RTOS
63+
void requestPollSoon(InputPollable *pollable);
64+
void queueInputEvent(const InputEvent *event);
65+
void processInputEventQueue();
66+
#endif
5367

5468
protected:
5569
int handleInputEvent(const InputEvent *event);
70+
71+
private:
72+
#ifdef HAS_FREE_RTOS
73+
QueueHandle_t inputEventQueue;
74+
QueueHandle_t pollSoonQueue;
75+
TaskHandle_t pollSoonTask;
76+
static void pollSoonWorker(void *p);
77+
#endif
5678
};
5779

5880
extern InputBroker *inputBroker;

0 commit comments

Comments
 (0)