mirror of
https://github.com/alexhopeoconnor/firmware.git
synced 2026-10-17 00:51:30 +10:00
Merge branch 'develop' into pioarduino
This commit is contained in:
@@ -275,9 +275,12 @@ void drawEntryHopSignal(OLEDDisplay *display, meshtastic_NodeInfoLite *node, int
|
||||
|
||||
int nameMaxWidth = getNodeNameMaxWidth(columnWidth, columnWidth - 25);
|
||||
int barsOffset = (currentResolution == ScreenResolution::High) ? (isLeftCol ? 20 : 24) : (isLeftCol ? 15 : 19);
|
||||
int hopOffset = (currentResolution == ScreenResolution::High) ? (isLeftCol ? 21 : 29) : (isLeftCol ? 13 : 17);
|
||||
constexpr int kBarCount = 4;
|
||||
constexpr int kBarWidth = 2;
|
||||
constexpr int kBarGap = 1;
|
||||
|
||||
int barsXOffset = columnWidth - barsOffset;
|
||||
int barsRightEdge = x + barsXOffset + ((kBarCount - 1) * (kBarWidth + kBarGap)) + kBarWidth;
|
||||
|
||||
const int nameX = x + ((currentResolution == ScreenResolution::High) ? 6 : 3);
|
||||
char nodeName[96];
|
||||
@@ -304,28 +307,35 @@ void drawEntryHopSignal(OLEDDisplay *display, meshtastic_NodeInfoLite *node, int
|
||||
}
|
||||
}
|
||||
|
||||
// Draw signal strength bars
|
||||
int bars = (node->snr > 5) ? 4 : (node->snr > 0) ? 3 : (node->snr > -5) ? 2 : (node->snr > -10) ? 1 : 0;
|
||||
int barWidth = 2;
|
||||
int barStartX = x + barsXOffset;
|
||||
int barStartY = y + 1 + (FONT_HEIGHT_SMALL / 2) + 2;
|
||||
const bool isZeroHop = node->has_hops_away && node->hops_away == 0;
|
||||
|
||||
for (int b = 0; b < 4; b++) {
|
||||
if (b < bars) {
|
||||
int height = (b * 2);
|
||||
display->fillRect(barStartX + (b * (barWidth + 1)), barStartY - height, barWidth, height);
|
||||
// Show signal only for direct neighbors (0 hops)
|
||||
if (isZeroHop) {
|
||||
int bars = (node->snr > 5) ? 4 : (node->snr > 0) ? 3 : (node->snr > -5) ? 2 : (node->snr > -10) ? 1 : 0;
|
||||
int barStartX = x + barsXOffset;
|
||||
int barStartY = y + 1 + (FONT_HEIGHT_SMALL / 2) + 2;
|
||||
|
||||
for (int b = 0; b < kBarCount; b++) {
|
||||
if (b < bars) {
|
||||
int height = (b * 2);
|
||||
display->fillRect(barStartX + (b * (kBarWidth + kBarGap)), barStartY - height, kBarWidth, height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw hop count
|
||||
char hopStr[6] = "";
|
||||
if (node->has_hops_away && node->hops_away > 0)
|
||||
snprintf(hopStr, sizeof(hopStr), "[%d]", node->hops_away);
|
||||
// Draw hop count + hop icon
|
||||
if (node->has_hops_away && node->hops_away > 0) {
|
||||
char hopCount[6];
|
||||
snprintf(hopCount, sizeof(hopCount), "%d", node->hops_away);
|
||||
|
||||
if (hopStr[0] != '\0') {
|
||||
int rightEdge = x + columnWidth - hopOffset;
|
||||
int textWidth = display->getStringWidth(hopStr);
|
||||
display->drawString(rightEdge - textWidth, y, hopStr);
|
||||
const int hopCountWidth = display->getStringWidth(hopCount);
|
||||
const int gap = 1;
|
||||
const int totalWidth = hopCountWidth + gap + hop_width;
|
||||
const int hopX = barsRightEdge - totalWidth;
|
||||
const int iconY = y + (FONT_HEIGHT_SMALL - hop_height) / 2;
|
||||
|
||||
display->drawString(hopX, y, hopCount);
|
||||
display->drawXbm(hopX + hopCountWidth + gap, iconY, hop_width, hop_height, hop);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -405,10 +405,10 @@ void UIRenderer::drawFavoriteNode(OLEDDisplay *display, OLEDDisplayUiState *stat
|
||||
}
|
||||
#endif
|
||||
|
||||
// === 2. Signal and Hops (combined on one line, if available) ===
|
||||
char signalHopsStr[32] = "";
|
||||
// === 2. Signal/Hops line (if available) ===
|
||||
bool haveSignal = false;
|
||||
int bars = 0;
|
||||
const char *qualityLabel = nullptr;
|
||||
|
||||
// Helper to get SNR limit based on modem preset
|
||||
auto getSnrLimit = [](meshtastic_Config_LoRaConfig_ModemPreset preset) -> float {
|
||||
@@ -429,80 +429,51 @@ void UIRenderer::drawFavoriteNode(OLEDDisplay *display, OLEDDisplayUiState *stat
|
||||
}
|
||||
};
|
||||
|
||||
// Calculate signal grade using modem preset and SNR only
|
||||
float snrLimit = getSnrLimit(config.lora.modem_preset);
|
||||
float snr = node->snr;
|
||||
|
||||
// Determine signal quality label and bars using SNR-only grading
|
||||
const char *qualityLabel = nullptr;
|
||||
|
||||
if (snr > snrLimit + 10) {
|
||||
qualityLabel = "Good";
|
||||
bars = 4;
|
||||
} else if (snr > snrLimit + 6) {
|
||||
qualityLabel = "Good";
|
||||
bars = 3;
|
||||
} else if (snr > snrLimit + 2) {
|
||||
qualityLabel = "Good";
|
||||
bars = 2;
|
||||
} else if (snr > snrLimit - 4) {
|
||||
qualityLabel = "Fair";
|
||||
bars = 1;
|
||||
} else {
|
||||
qualityLabel = "Bad";
|
||||
bars = 1;
|
||||
}
|
||||
|
||||
// Add extra spacing on the left if we have an API connection to account for the common footer icons
|
||||
const char *leftSideSpacing =
|
||||
graphics::isAPIConnected(service->api_state) ? (currentResolution == ScreenResolution::High ? " " : " ") : " ";
|
||||
const bool isZeroHop = node->has_hops_away && node->hops_away == 0;
|
||||
|
||||
// --- Build the Signal/Hops line ---
|
||||
// Only show signal if we have valid SNR
|
||||
if (snr > -100 && snr != 0) {
|
||||
snprintf(signalHopsStr, sizeof(signalHopsStr), "%sSig:%s", leftSideSpacing, qualityLabel);
|
||||
haveSignal = true;
|
||||
}
|
||||
|
||||
if (node->hops_away > 0) {
|
||||
size_t len = strlen(signalHopsStr);
|
||||
if (haveSignal) {
|
||||
snprintf(signalHopsStr + len, sizeof(signalHopsStr) - len, " [#]");
|
||||
} else {
|
||||
snprintf(signalHopsStr, sizeof(signalHopsStr), "[#]");
|
||||
}
|
||||
}
|
||||
|
||||
if (signalHopsStr[0]) {
|
||||
int yPos = getTextPositions(display)[line++];
|
||||
int curX = x;
|
||||
|
||||
// Split combined string into signal text and hop suffix
|
||||
char sigPart[20] = "";
|
||||
const char *hopPart = nullptr;
|
||||
|
||||
char *bracket = strchr(signalHopsStr, '[');
|
||||
if (bracket) {
|
||||
size_t n = (size_t)(bracket - signalHopsStr);
|
||||
if (n >= sizeof(sigPart))
|
||||
n = sizeof(sigPart) - 1;
|
||||
memcpy(sigPart, signalHopsStr, n);
|
||||
sigPart[n] = '\0';
|
||||
|
||||
// Trim trailing spaces
|
||||
while (strlen(sigPart) && sigPart[strlen(sigPart) - 1] == ' ') {
|
||||
sigPart[strlen(sigPart) - 1] = '\0';
|
||||
// Signal text/bars are only for direct (zero-hop) nodes with valid SNR.
|
||||
if (isZeroHop) {
|
||||
float snr = node->snr;
|
||||
if (snr > -100 && snr != 0) {
|
||||
float snrLimit = getSnrLimit(config.lora.modem_preset);
|
||||
// Determine signal quality label and bars using SNR-only grading.
|
||||
if (snr > snrLimit + 10) {
|
||||
qualityLabel = "Good";
|
||||
bars = 4;
|
||||
} else if (snr > snrLimit + 6) {
|
||||
qualityLabel = "Good";
|
||||
bars = 3;
|
||||
} else if (snr > snrLimit + 2) {
|
||||
qualityLabel = "Good";
|
||||
bars = 2;
|
||||
} else if (snr > snrLimit - 4) {
|
||||
qualityLabel = "Fair";
|
||||
bars = 1;
|
||||
} else {
|
||||
qualityLabel = "Bad";
|
||||
bars = 1;
|
||||
}
|
||||
|
||||
hopPart = bracket; // "[n Hop(s)]"
|
||||
} else {
|
||||
strncpy(sigPart, signalHopsStr, sizeof(sigPart) - 1);
|
||||
sigPart[sizeof(sigPart) - 1] = '\0';
|
||||
haveSignal = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Draw signal quality text
|
||||
display->drawString(curX, yPos, sigPart);
|
||||
curX += display->getStringWidth(sigPart) + 4;
|
||||
const bool showHops = node->has_hops_away && node->hops_away > 0;
|
||||
|
||||
if (haveSignal || showHops) {
|
||||
int yPos = getTextPositions(display)[line++];
|
||||
int curX = x + display->getStringWidth(leftSideSpacing);
|
||||
|
||||
// Draw signal quality text for zero-hop nodes when present.
|
||||
if (haveSignal && qualityLabel) {
|
||||
char signalLabel[20];
|
||||
snprintf(signalLabel, sizeof(signalLabel), "Sig:%s", qualityLabel);
|
||||
display->drawString(curX, yPos, signalLabel);
|
||||
curX += display->getStringWidth(signalLabel) + 4;
|
||||
}
|
||||
|
||||
// Draw signal bars (skip on UltraLow, text only)
|
||||
if (currentResolution != ScreenResolution::UltraLow && haveSignal && bars > 0) {
|
||||
@@ -541,12 +512,12 @@ void UIRenderer::drawFavoriteNode(OLEDDisplay *display, OLEDDisplayUiState *stat
|
||||
curX += (kMaxBars * barWidth) + ((kMaxBars - 1) * barGap) + 2;
|
||||
}
|
||||
|
||||
// Draw hops AFTER the bars as: [ number + hop icon ]
|
||||
if (hopPart && node->hops_away > 0) {
|
||||
|
||||
// open bracket
|
||||
display->drawString(curX, yPos, "[");
|
||||
curX += display->getStringWidth("[") + 1;
|
||||
// Draw hops for non-zero-hop nodes as: number + hop icon.
|
||||
// This path is mutually exclusive with the zero-hop signal-bars path above.
|
||||
if (showHops) {
|
||||
// hop label
|
||||
display->drawString(curX, yPos, "Hop:");
|
||||
curX += display->getStringWidth("Hop:") + 2;
|
||||
|
||||
// hop count
|
||||
char hopCount[6];
|
||||
@@ -558,9 +529,6 @@ void UIRenderer::drawFavoriteNode(OLEDDisplay *display, OLEDDisplayUiState *stat
|
||||
const int iconY = yPos + (FONT_HEIGHT_SMALL - hop_height) / 2;
|
||||
display->drawXbm(curX, iconY, hop_width, hop_height, hop);
|
||||
curX += hop_width + 1;
|
||||
|
||||
// closing bracket
|
||||
display->drawString(curX, yPos, "]");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
|
||||
NicheGraphics parallel E-Ink driver for the LilyGo T5-S3-ePaper-Pro (ED047TC1).
|
||||
|
||||
InkHUD buffer format : 1bpp, horizontal bytes, MSB = leftmost pixel, 1 = white
|
||||
FastEPD buffer format: 1bpp, horizontal bytes, MSB = leftmost pixel, 1 = white
|
||||
|
||||
Both formats share the same pixel layout and polarity (1 = white, 0 = black).
|
||||
The InkHUD safe-area buffer (944×523) is copied into the centre of the physical
|
||||
960×540 FastEPD buffer so content clears the panel's inactive edge border.
|
||||
See ED047TC1.h for the H_OFFSET_BYTES / V_OFFSET_TOP / V_OFFSET_BOTTOM constants.
|
||||
|
||||
*/
|
||||
|
||||
// Ruler diagnostic — uncomment to draw calibration lines at each physical edge.
|
||||
// #define EINK_EDGE_LINES
|
||||
|
||||
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
|
||||
#ifdef T5_S3_EPAPER_PRO
|
||||
|
||||
#include "./ED047TC1.h"
|
||||
|
||||
#include "FastEPD.h"
|
||||
#include "configuration.h"
|
||||
|
||||
using namespace NicheGraphics::Drivers;
|
||||
|
||||
void ED047TC1::begin(SPIClass *spi, uint8_t pin_dc, uint8_t pin_cs, uint8_t pin_busy, uint8_t pin_rst)
|
||||
{
|
||||
// Parallel display — SPI parameters are not used
|
||||
(void)spi;
|
||||
(void)pin_dc;
|
||||
(void)pin_cs;
|
||||
(void)pin_busy;
|
||||
(void)pin_rst;
|
||||
|
||||
epaper = new FASTEPD;
|
||||
|
||||
#if defined(T5_S3_EPAPER_PRO_V1)
|
||||
epaper->initPanel(BB_PANEL_LILYGO_T5PRO, 28000000);
|
||||
#elif defined(T5_S3_EPAPER_PRO_V2)
|
||||
epaper->initPanel(BB_PANEL_LILYGO_T5PRO_V2, 28000000);
|
||||
// Initialize all PCA9535 port-0 pins as outputs / HIGH
|
||||
for (int i = 0; i < 8; i++) {
|
||||
epaper->ioPinMode(i, OUTPUT);
|
||||
epaper->ioWrite(i, HIGH);
|
||||
}
|
||||
#else
|
||||
#error "ED047TC1 driver: unsupported variant — define T5_S3_EPAPER_PRO_V1 or T5_S3_EPAPER_PRO_V2"
|
||||
#endif
|
||||
|
||||
epaper->setMode(BB_MODE_1BPP);
|
||||
epaper->clearWhite();
|
||||
epaper->fullUpdate(true); // Blocking initial clear
|
||||
}
|
||||
|
||||
void ED047TC1::update(uint8_t *imageData, UpdateTypes type)
|
||||
{
|
||||
if (!epaper)
|
||||
return;
|
||||
|
||||
// InkHUD renders into a DISPLAY_WIDTH × DISPLAY_HEIGHT safe-area buffer.
|
||||
// We need to place that into the centre of the physical 960×540 FastEPD buffer,
|
||||
// leaving blank margins at every edge to avoid the panel's inactive border.
|
||||
const uint32_t srcRowBytes = (DISPLAY_WIDTH + 7) / 8; // bytes per row in InkHUD buffer (118)
|
||||
const uint32_t dstRowBytes = (960 + 7) / 8; // bytes per row in physical buffer (120)
|
||||
const uint32_t dstTotalRows = 540;
|
||||
|
||||
uint8_t *cur = epaper->currentBuffer();
|
||||
|
||||
// Fill physical buffer with white (0xFF = white in FastEPD 1bpp)
|
||||
memset(cur, 0xFF, dstRowBytes * dstTotalRows);
|
||||
|
||||
// Copy each InkHUD row into the physical buffer with horizontal + vertical offsets
|
||||
for (uint32_t row = 0; row < DISPLAY_HEIGHT; row++) {
|
||||
const uint8_t *srcRow = imageData + row * srcRowBytes;
|
||||
uint8_t *dstRow = cur + (row + V_OFFSET_TOP) * dstRowBytes + H_OFFSET_BYTES;
|
||||
memcpy(dstRow, srcRow, srcRowBytes);
|
||||
}
|
||||
|
||||
#ifdef EINK_EDGE_LINES
|
||||
// Draw a 1px black box at the exact boundary of the safe area within the
|
||||
// physical buffer. If the margins are correct, all 4 lines should be
|
||||
// fully visible and right at the edge of the usable display area.
|
||||
|
||||
auto setPixelBlack = [&](uint32_t col, uint32_t row) { cur[row * dstRowBytes + col / 8] &= ~(0x80 >> (col % 8)); };
|
||||
|
||||
const uint32_t safeX = H_OFFSET_BYTES * 8;
|
||||
const uint32_t safeY = V_OFFSET_TOP;
|
||||
const uint32_t safeW = DISPLAY_WIDTH;
|
||||
const uint32_t safeH = DISPLAY_HEIGHT;
|
||||
|
||||
// Top edge: horizontal line at safeY
|
||||
for (uint32_t col = safeX; col < safeX + safeW; col++)
|
||||
setPixelBlack(col, safeY);
|
||||
|
||||
// Bottom edge: horizontal line at safeY + safeH - 1
|
||||
for (uint32_t col = safeX; col < safeX + safeW; col++)
|
||||
setPixelBlack(col, safeY + safeH - 1);
|
||||
|
||||
// Left edge: vertical line at safeX
|
||||
for (uint32_t row = safeY; row < safeY + safeH; row++)
|
||||
setPixelBlack(safeX, row);
|
||||
|
||||
// Right edge: vertical line at safeX + safeW - 1
|
||||
for (uint32_t row = safeY; row < safeY + safeH; row++)
|
||||
setPixelBlack(safeX + safeW - 1, row);
|
||||
#endif
|
||||
|
||||
if (type == FULL) {
|
||||
epaper->fullUpdate(CLEAR_SLOW, false);
|
||||
epaper->backupPlane(); // Sync pPrevious so next partialUpdate has a correct baseline
|
||||
} else {
|
||||
// FAST: true partial update — compares pCurrent vs pPrevious and only applies
|
||||
// the update waveform to rows that actually changed. Unchanged rows get a neutral
|
||||
// signal (no visible effect). partialUpdate() updates pPrevious internally.
|
||||
epaper->partialUpdate(false, 0, dstTotalRows - 1);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // T5_S3_EPAPER_PRO
|
||||
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
|
||||
E-Ink display driver adapter
|
||||
- ED047TC1 (via FastEPD library)
|
||||
- Manufacturer: E Ink / used in LilyGo T5-E-Paper-S3-Pro
|
||||
- Size: 4.7 inch
|
||||
- Physical resolution: 960px x 540px
|
||||
- Interface: 8-bit parallel (NOT SPI)
|
||||
|
||||
Unlike the other NicheGraphics EInk drivers, this one drives a parallel e-paper
|
||||
panel via the FastEPD library. SPI parameters passed to begin() are ignored.
|
||||
|
||||
The ED047TC1 panel has an inactive pixel border on all four edges (~4–8 physical
|
||||
pixels). DISPLAY_WIDTH / DISPLAY_HEIGHT expose a reduced "safe area" to InkHUD so
|
||||
that content is never drawn into this dead zone. The update() method copies the
|
||||
InkHUD frame buffer into the centre of the larger physical 960×540 buffer, using
|
||||
H_OFFSET_BYTES (horizontal, whole bytes = 8 pixels per byte),
|
||||
V_OFFSET_TOP and V_OFFSET_BOTTOM (vertical, pixel rows) to position it.
|
||||
|
||||
Changing these constants shifts content inward from each physical edge:
|
||||
H_OFFSET_BYTES = 1 → 8px left margin, 8px right margin (960 – 8 – 8 = 944)
|
||||
V_OFFSET_TOP = 9 → 9px top margin (asymmetric: top ≠ bottom)
|
||||
V_OFFSET_BOTTOM = 8 → 8px bottom margin (540 – 9 – 8 = 523)
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
|
||||
|
||||
#include "configuration.h"
|
||||
|
||||
#include "./EInk.h"
|
||||
|
||||
// Forward declare to avoid pulling FastEPD into all translation units
|
||||
class FASTEPD;
|
||||
|
||||
namespace NicheGraphics::Drivers
|
||||
{
|
||||
|
||||
class ED047TC1 : public EInk
|
||||
{
|
||||
// Safe-area dimensions exposed to InkHUD (physical panel is 960×540).
|
||||
//
|
||||
// The ED047TC1 has an inactive pixel border on all physical edges.
|
||||
// The physical buffer coordinates do NOT directly match the visual orientation
|
||||
// due to FastEPD's portrait scan direction and InkHUD's rotation=3 (270° CW):
|
||||
//
|
||||
// Physical buffer Visual on device (rotation=3)
|
||||
// ───────────────── ──────────────────────────────
|
||||
// Physical LEFT cols → Visual TOP edge
|
||||
// Physical RIGHT cols → Visual BOTTOM edge
|
||||
// Physical TOP rows → Visual RIGHT edge
|
||||
// Physical BOTTOM rows → Visual LEFT edge
|
||||
//
|
||||
// Offset constants shift the InkHUD safe-area away from each physical dead zone:
|
||||
// H_OFFSET_BYTES : whole bytes from physical left (8px per byte, affects visual TOP)
|
||||
// Physical right margin = 960 − H_OFFSET_BYTES×8 − DISPLAY_WIDTH (affects visual BOTTOM)
|
||||
// V_OFFSET_TOP : pixel rows from physical top (affects visual RIGHT)
|
||||
// V_OFFSET_BOTTOM: pixel rows from physical bottom (affects visual LEFT)
|
||||
//
|
||||
// Calibrated by flashing a 1px border box and adjusting until all 4 sides are visible.
|
||||
|
||||
static constexpr uint16_t DISPLAY_WIDTH = 944; // 960 − H_OFFSET_BYTES×8 − right_margin (8+8 = 16px)
|
||||
static constexpr uint16_t DISPLAY_HEIGHT = 523; // 540 − V_OFFSET_TOP − V_OFFSET_BOTTOM (9+8 = 17px)
|
||||
|
||||
static constexpr uint8_t H_OFFSET_BYTES = 1; // visual TOP : 8px physical left margin
|
||||
// visual BOTTOM: 960−8−944=8px physical right margin
|
||||
static constexpr uint8_t V_OFFSET_TOP = 9; // visual RIGHT : CONFIRMED OK
|
||||
static constexpr uint8_t V_OFFSET_BOTTOM = 8; // visual LEFT : 8px physical bottom margin
|
||||
|
||||
static constexpr UpdateTypes supported = static_cast<UpdateTypes>(FULL | FAST);
|
||||
|
||||
public:
|
||||
ED047TC1() : EInk(DISPLAY_WIDTH, DISPLAY_HEIGHT, supported) {}
|
||||
|
||||
// EInk interface — SPI params are not used for this parallel display
|
||||
void begin(SPIClass *spi, uint8_t pin_dc, uint8_t pin_cs, uint8_t pin_busy, uint8_t pin_rst = 0xFF) override;
|
||||
void update(uint8_t *imageData, UpdateTypes type) override;
|
||||
|
||||
protected:
|
||||
bool isUpdateDone() override { return true; } // FastEPD updates are blocking
|
||||
|
||||
private:
|
||||
FASTEPD *epaper = nullptr;
|
||||
};
|
||||
|
||||
} // namespace NicheGraphics::Drivers
|
||||
|
||||
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -88,8 +88,12 @@ class AppletFont
|
||||
|
||||
// Greek
|
||||
#include "graphics/niche/Fonts/FreeSans12pt_Win1253.h"
|
||||
#include "graphics/niche/Fonts/FreeSans18pt_Win1253.h"
|
||||
#include "graphics/niche/Fonts/FreeSans24pt_Win1253.h"
|
||||
#include "graphics/niche/Fonts/FreeSans6pt_Win1253.h"
|
||||
#include "graphics/niche/Fonts/FreeSans9pt_Win1253.h"
|
||||
#define FREESANS_24PT_WIN1253 InkHUD::AppletFont(FreeSans24pt_Win1253, InkHUD::AppletFont::WINDOWS_1253, -5, 3)
|
||||
#define FREESANS_18PT_WIN1253 InkHUD::AppletFont(FreeSans18pt_Win1253, InkHUD::AppletFont::WINDOWS_1253, -4, 2)
|
||||
#define FREESANS_12PT_WIN1253 InkHUD::AppletFont(FreeSans12pt_Win1253, InkHUD::AppletFont::WINDOWS_1253, -3, 1)
|
||||
#define FREESANS_9PT_WIN1253 InkHUD::AppletFont(FreeSans9pt_Win1253, InkHUD::AppletFont::WINDOWS_1253, -2, -1)
|
||||
#define FREESANS_6PT_WIN1253 InkHUD::AppletFont(FreeSans6pt_Win1253, InkHUD::AppletFont::WINDOWS_1253, -1, -2)
|
||||
|
||||
@@ -143,6 +143,10 @@ int32_t ButtonThread::runOnce()
|
||||
leadUpSequenceActive = false;
|
||||
resetLeadUpSequence();
|
||||
}
|
||||
#ifdef INPUT_DEBUG
|
||||
if (buttonCurrentlyPressed)
|
||||
LOG_WARN("Button held for %u ms", millis() - buttonPressStartTime);
|
||||
#endif
|
||||
|
||||
// Progressive lead-up sound system
|
||||
if (!_suppressLeadUp && buttonCurrentlyPressed && (millis() - buttonPressStartTime) >= BUTTON_LEADUP_MS) {
|
||||
@@ -311,7 +315,8 @@ int32_t ButtonThread::runOnce()
|
||||
void ButtonThread::attachButtonInterrupts()
|
||||
{
|
||||
// Interrupt for user button, during normal use. Improves responsiveness.
|
||||
attachInterrupt(_pinNum, _intRoutine, CHANGE);
|
||||
if (_intRoutine != nullptr)
|
||||
attachInterrupt(_pinNum, _intRoutine, CHANGE);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -320,7 +325,8 @@ void ButtonThread::attachButtonInterrupts()
|
||||
*/
|
||||
void ButtonThread::detachButtonInterrupts()
|
||||
{
|
||||
detachInterrupt(_pinNum);
|
||||
if (_intRoutine != nullptr)
|
||||
detachInterrupt(_pinNum);
|
||||
}
|
||||
|
||||
#ifdef ARCH_ESP32
|
||||
|
||||
@@ -29,7 +29,8 @@ void TouchScreenImpl1::init()
|
||||
return;
|
||||
#else
|
||||
TouchScreenBase::init(true);
|
||||
inputBroker->registerSource(this);
|
||||
if (inputBroker)
|
||||
inputBroker->registerSource(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -455,6 +455,15 @@ template <typename T> void SX126xInterface<T>::resetAGC()
|
||||
// RX boosted gain mode
|
||||
lora.setRxBoostedGainMode(config.lora.sx126x_rx_boosted_gain);
|
||||
|
||||
// Re-apply the undocumented 0x8B5 RX sensitivity patch that was set in init().
|
||||
// The CALIBRATE_ALL (0x7F) command above clears bit 0 of register 0x8B5, which
|
||||
// silently removes the RX sensitivity improvement introduced in #9571 / #9777.
|
||||
// Without this re-apply, every SX1262 node loses its RX boost ~60s after boot
|
||||
// and never recovers until reboot. See empirical evidence in the PR description.
|
||||
if (module.SPIsetRegValue(0x8B5, 0x01, 0, 0) != RADIOLIB_ERR_NONE) {
|
||||
LOG_WARN("SX126x resetAGC: failed to re-apply 0x8B5 RX sensitivity patch");
|
||||
}
|
||||
|
||||
// 6. Resume receiving
|
||||
startReceive();
|
||||
}
|
||||
|
||||
@@ -81,7 +81,9 @@ meshtastic_UserLite TypeConversions::ConvertToUserLite(meshtastic_User user)
|
||||
meshtastic_UserLite lite = meshtastic_UserLite_init_default;
|
||||
|
||||
strncpy(lite.long_name, user.long_name, sizeof(lite.long_name));
|
||||
lite.long_name[sizeof(lite.long_name) - 1] = '\0';
|
||||
strncpy(lite.short_name, user.short_name, sizeof(lite.short_name));
|
||||
lite.short_name[sizeof(lite.short_name) - 1] = '\0';
|
||||
lite.hw_model = user.hw_model;
|
||||
lite.role = user.role;
|
||||
lite.is_licensed = user.is_licensed;
|
||||
@@ -99,7 +101,9 @@ meshtastic_User TypeConversions::ConvertToUser(uint32_t nodeNum, meshtastic_User
|
||||
|
||||
snprintf(user.id, sizeof(user.id), "!%08x", nodeNum);
|
||||
strncpy(user.long_name, lite.long_name, sizeof(user.long_name));
|
||||
user.long_name[sizeof(user.long_name) - 1] = '\0';
|
||||
strncpy(user.short_name, lite.short_name, sizeof(user.short_name));
|
||||
user.short_name[sizeof(user.short_name) - 1] = '\0';
|
||||
user.hw_model = lite.hw_model;
|
||||
user.role = lite.role;
|
||||
user.is_licensed = lite.is_licensed;
|
||||
|
||||
@@ -285,7 +285,11 @@ typedef enum _meshtastic_Config_LoRaConfig_RegionCode {
|
||||
/* Nepal 865MHz */
|
||||
meshtastic_Config_LoRaConfig_RegionCode_NP_865 = 25,
|
||||
/* Brazil 902MHz */
|
||||
meshtastic_Config_LoRaConfig_RegionCode_BR_902 = 26
|
||||
meshtastic_Config_LoRaConfig_RegionCode_BR_902 = 26,
|
||||
/* ITU Region 1 Amateur Radio 2m band (144-146 MHz) */
|
||||
meshtastic_Config_LoRaConfig_RegionCode_ITU1_2M = 27,
|
||||
/* ITU Region 2 / 3 Amateur Radio 2m band (144-148 MHz) */
|
||||
meshtastic_Config_LoRaConfig_RegionCode_ITU23_2M = 28
|
||||
} meshtastic_Config_LoRaConfig_RegionCode;
|
||||
|
||||
/* Standard predefined channel settings
|
||||
@@ -702,8 +706,8 @@ extern "C" {
|
||||
#define _meshtastic_Config_DisplayConfig_CompassOrientation_ARRAYSIZE ((meshtastic_Config_DisplayConfig_CompassOrientation)(meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_270_INVERTED+1))
|
||||
|
||||
#define _meshtastic_Config_LoRaConfig_RegionCode_MIN meshtastic_Config_LoRaConfig_RegionCode_UNSET
|
||||
#define _meshtastic_Config_LoRaConfig_RegionCode_MAX meshtastic_Config_LoRaConfig_RegionCode_BR_902
|
||||
#define _meshtastic_Config_LoRaConfig_RegionCode_ARRAYSIZE ((meshtastic_Config_LoRaConfig_RegionCode)(meshtastic_Config_LoRaConfig_RegionCode_BR_902+1))
|
||||
#define _meshtastic_Config_LoRaConfig_RegionCode_MAX meshtastic_Config_LoRaConfig_RegionCode_ITU23_2M
|
||||
#define _meshtastic_Config_LoRaConfig_RegionCode_ARRAYSIZE ((meshtastic_Config_LoRaConfig_RegionCode)(meshtastic_Config_LoRaConfig_RegionCode_ITU23_2M+1))
|
||||
|
||||
#define _meshtastic_Config_LoRaConfig_ModemPreset_MIN meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST
|
||||
#define _meshtastic_Config_LoRaConfig_ModemPreset_MAX meshtastic_Config_LoRaConfig_ModemPreset_LONG_TURBO
|
||||
|
||||
Reference in New Issue
Block a user