Merge upstream/main (v1.16.0) into wio-unified

Merge 254 upstream commits. Highlights relevant to the Wio fork: native
NRF52 companion power-saving (sleep when !hasPendingWork), preamble 16->32
for SF<9, generic sensor-registration model, CMD_SEND_RAW_PACKET, isEink()
display abstraction, KEEP_DISPLAY_ON_USB, contacts-sync/transient fixes.

Conflicts resolved (11 files):
- buzzer.h/.cpp: keep NRF52 include guard + our begin()->startup(); fold in
  upstream doc comment.
- platformio (wio + eink): keep our slim env layout, add upstream kiss_modem
  env (+ debug_tool=stlink on eink ble).
- GxEPDDisplay.h: take upstream isEink() override.
- EnvironmentSensorManager.h: take upstream's wider #if guard.
- DataStore.cpp: take upstream saveContacts(filter) signature, keep our
  ::openWrite (member openWrite would shadow the global 2-arg overload).
- main.cpp: keep our watchdog init + add board.onBootComplete(); adopt
  upstream's `if(!hasPendingWork()) sleep` loop.
- MyMesh.h: version -> v1.16-solo.0, build date 6 Jun 2026.
- MyMesh.cpp: keep both CMD codes (SCREENSHOT 66 + RAW_PACKET 65), both field
  inits, both handlers, our screenshot fns + upstream saveContacts/save_filter,
  upstream hasPendingWork() + our MyMeshBot include.
- UITask.cpp: keep our solo splash/clock page/snprintf/buzzer init; merge
  auto-off (+ opt-in KEEP_DISPLAY_ON_USB); merge low-batt shutdown (our EMA +
  prefs threshold + upstream's !isExternalPowered() guard and eink-aware delay).

Post-merge drift fixes (upstream API/architecture changes, not conflicts):
- applyTxPower(): radio_set_tx_power() removed upstream -> radio_driver.setTxPower().
- Sensor refactor dropped the per-sensor *_initialized flags our
  getAvailableLPPTypes() relied on; removed that override and the SENSORS page
  now derives available LPP types from the populated sensors_lpp buffer.

README kept ours via .gitattributes merge=ours. Builds verified on all 5 Wio
envs (dual, eink dual, radio_ble, dual_dev, eink_dual_dev). Not yet
hardware-verified.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Jakub
2026-06-06 17:21:41 +02:00
co-authored by Claude Opus 4.8
356 changed files with 6668 additions and 3108 deletions
+1
View File
@@ -17,6 +17,7 @@ public:
int height() const { return _h; }
virtual bool isOn() = 0;
virtual bool isEink() { return false; } // default to non-eink, override in eink drivers
virtual void turnOn() = 0;
virtual void turnOff() = 0;
virtual void clear() = 0;
+1
View File
@@ -26,6 +26,7 @@ public:
}
bool begin();
bool isOn() override { return _isOn; }
bool isEink() override { return true; }
void turnOn() override;
void turnOff() override;
void clear() override;
+1
View File
@@ -22,6 +22,7 @@ public:
bool begin();
bool isOn() override { return _isOn; }
bool isEink() override { return true; }
void turnOn() override;
void turnOff() override;
void clear() override;
+1
View File
@@ -125,6 +125,7 @@ public:
bool begin();
bool isOn() override { return _isOn; }
bool isEink() override { return true; }
void turnOn() override;
void turnOff() override;
void clear() override;
+3 -3
View File
@@ -842,11 +842,11 @@ void OLEDDisplay::drawLogBuffer(uint16_t xMove, uint16_t yMove) {
uint16_t lastPos = 0;
for (uint16_t i=0;i<this->logBufferFilled;i++){
// Everytime we have a \n print
// Every time we have a \n print
if (this->logBuffer[i] == 10) {
length++;
// Draw string on line `line` from lastPos to length
// Passing 0 as the lenght because we are in TEXT_ALIGN_LEFT
// Passing 0 as the length because we are in TEXT_ALIGN_LEFT
drawStringInternal(xMove, yMove + (line++) * lineHeight, &this->logBuffer[lastPos], length, 0, false);
// Remember last pos
lastPos = i;
@@ -1155,7 +1155,7 @@ void OLEDDisplay::setFontTableLookupFunction(FontTableLookupFunction function) {
char DefaultFontTableLookup(const uint8_t ch) {
// UTF-8 to font table index converter
// Code form http://playground.arduino.cc/Main/Utf8ascii
// Code from http://playground.arduino.cc/Main/Utf8ascii
static uint8_t LASTCHAR;
if (ch < 128) { // Standard ASCII-set 0..0x7F handling
+2 -2
View File
@@ -60,7 +60,7 @@ private:
};
#else
#error "Unkown operating system"
#error "Unknown operating system"
#endif
#include "OLEDDisplayFonts.h"
@@ -160,7 +160,7 @@ class OLEDDisplay : public Print {
#elif __MBED__
class OLEDDisplay : public Stream {
#else
#error "Unkown operating system"
#error "Unknown operating system"
#endif
public:
+4 -1
View File
@@ -28,7 +28,10 @@ bool ST7735Display::begin() {
#endif
digitalWrite(PIN_TFT_RST, HIGH);
#if defined(HELTEC_TRACKER_V2) || defined(HELTEC_T096)
#if defined(HELTEC_T1)
display.initR(INITR_MINI160x80);
display.setRotation(DISPLAY_ROTATION);
#elif defined(HELTEC_TRACKER_V2) || defined(HELTEC_T096)
display.initR(INITR_MINI160x80);
display.setRotation(DISPLAY_ROTATION);
uint8_t madctl = ST77XX_MADCTL_MY | ST77XX_MADCTL_MV |ST7735_MADCTL_BGR;//Adjust color to BGR
+1 -7
View File
@@ -27,12 +27,6 @@ bool ST7789LCDDisplay::begin() {
pinMode(PIN_TFT_LEDA_CTL, OUTPUT);
digitalWrite(PIN_TFT_LEDA_CTL, HIGH);
}
if (PIN_TFT_RST != -1) {
pinMode(PIN_TFT_RST, OUTPUT);
digitalWrite(PIN_TFT_RST, LOW);
delay(10);
digitalWrite(PIN_TFT_RST, HIGH);
}
// Im not sure if this is just a t-deck problem or not, if your display is slow try this.
#if defined(LILYGO_TDECK) || defined(HELTEC_LORA_V4_TFT)
@@ -166,4 +160,4 @@ uint16_t ST7789LCDDisplay::getTextWidth(const char* str) {
void ST7789LCDDisplay::endFrame() {
// display.display();
}
}
+127
View File
@@ -0,0 +1,127 @@
#pragma once
#include "DisplayDriver.h"
#include <U8g2lib.h>
#include <Wire.h>
#ifndef DISPLAY_ADDRESS
#define DISPLAY_ADDRESS 0x3C
#endif
#ifndef OLED_WIDTH
#define OLED_WIDTH 72
#endif
#ifndef OLED_HEIGHT
#define OLED_HEIGHT 40
#endif
class U8g2Display : public DisplayDriver {
// U8g2 constructor for SSD1306/SSD1315 72×40 panel — handles all
// GDDRAM column/page offsets, SETMULTIPLEX, SETDISPLAYOFFSET internally
U8G2_SSD1306_72X40_ER_F_HW_I2C _u8g2;
bool _isOn;
uint8_t _drawColor;
// Font metrics for current font (cached on setTextSize)
uint8_t _fontAscent;
uint8_t _fontHeight;
void applyFont(int sz) {
if (sz >= 2) {
_u8g2.setFont(u8g2_font_6x10_mr); // slightly larger font for better readability. TODO: more font sizes?
} else {
_u8g2.setFont(u8g2_font_5x7_mr);
}
_fontAscent = _u8g2.getAscent();
_fontHeight = _u8g2.getAscent() - _u8g2.getDescent();
}
public:
U8g2Display() : DisplayDriver(OLED_WIDTH, OLED_HEIGHT),
_u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE),
_isOn(false), _drawColor(1), _fontAscent(5), _fontHeight(6) {}
bool begin() {
// Wire must already be initialised by board.begin() before this is called
bool ok = _u8g2.begin();
if (ok) {
_u8g2.setI2CAddress(DISPLAY_ADDRESS * 2); // U8g2 uses 8-bit address
_u8g2.setFontPosTop(); // y coordinate = top of text, not baseline
_u8g2.setFontMode(1); // transparent background
applyFont(1); // default to compact font
_isOn = true;
}
return ok;
}
bool isOn() override { return _isOn; }
void turnOn() override {
_u8g2.setPowerSave(0);
_isOn = true;
}
void turnOff() override {
_u8g2.setPowerSave(1);
_isOn = false;
}
void clear() override {
_u8g2.clearBuffer();
_u8g2.sendBuffer();
}
void startFrame(Color bkg = DARK) override {
_u8g2.clearBuffer();
_drawColor = 1;
_u8g2.setDrawColor(1);
applyFont(1);
}
void setTextSize(int sz) override {
applyFont(sz);
}
void setColor(Color c) override {
_drawColor = (c != DARK) ? 1 : 0;
_u8g2.setDrawColor(_drawColor);
}
void setCursor(int x, int y) override {
_cursorX = x;
_cursorY = y;
}
void print(const char* str) override {
_u8g2.setDrawColor(_drawColor);
_u8g2.drawStr(_cursorX, _cursorY, str);
}
void fillRect(int x, int y, int w, int h) override {
_u8g2.setDrawColor(_drawColor);
_u8g2.drawBox(x, y, w, h);
}
void drawRect(int x, int y, int w, int h) override {
_u8g2.setDrawColor(_drawColor);
_u8g2.drawFrame(x, y, w, h);
}
void drawXbm(int x, int y, const uint8_t* bits, int w, int h) override {
_u8g2.setDrawColor(1);
_u8g2.drawXBM(x, y, w, h, bits);
}
uint16_t getTextWidth(const char* str) override {
return _u8g2.getStrWidth(str);
}
void endFrame() override {
_u8g2.sendBuffer();
}
private:
int _cursorX = 0;
int _cursorY = 0;
};
+2 -1
View File
@@ -1,3 +1,4 @@
#include "Arduino.h"
#ifdef PIN_BUZZER
#include "buzzer.h"
@@ -7,7 +8,7 @@ void genericBuzzer::begin() {
digitalWrite(PIN_BUZZER_EN, HIGH);
#endif
pinMode(PIN_BUZZER, OUTPUT);
digitalWrite(PIN_BUZZER, LOW);
digitalWrite(PIN_BUZZER, LOW); // need to pull low by default to avoid extreme power draw
startup();
}
+15
View File
@@ -2,10 +2,25 @@
#include <Arduino.h>
// NRF52 uses a custom non-blocking RTTTL player (see buzzer.cpp); only the
// other platforms pull in the NonBlockingRtttl library here.
#if !defined(NRF52_PLATFORM)
#include <NonBlockingRtttl.h>
#endif
/* class abstracts underlying RTTTL library
Just a simple implementation to start. At the moment use same
melody for message and discovery
Suggest enum type for different sounds
- on message
- on discovery
TODO
- make message ring tone configurable
*/
class genericBuzzer
{
public: