thinknode fixes

This commit is contained in:
liquidraver
2026-03-02 15:37:36 +01:00
parent 99784d5856
commit 6cb80a31af
6 changed files with 98 additions and 8 deletions
+36
View File
@@ -6,6 +6,7 @@
#include <zephyr/kernel.h>
#include <zephyr/sys/reboot.h>
#include <zephyr/drivers/sensor.h>
#include <zephyr/drivers/gpio.h>
#include <stdio.h>
#include <string.h>
@@ -18,6 +19,15 @@
#define NRF52_GPREGRET 1
#endif
/* LoRa TX activity LED (optional — defined per-board via DT alias) */
#if DT_NODE_EXISTS(DT_ALIAS(lora_tx_led))
static const struct gpio_dt_spec tx_led =
GPIO_DT_SPEC_GET(DT_ALIAS(lora_tx_led), gpios);
#define HAS_TX_LED 1
#else
#define HAS_TX_LED 0
#endif
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(zephcore_board, CONFIG_ZEPHCORE_BOARD_LOG_LEVEL);
@@ -55,6 +65,18 @@ static const struct device *vbat_enable_dev = NULL;
#define VBAT_ADC_SAMPLES 8
#endif
/* Initialize TX LED GPIO at boot */
#if HAS_TX_LED
static int tx_led_init(void)
{
if (gpio_is_ready_dt(&tx_led)) {
gpio_pin_configure_dt(&tx_led, GPIO_OUTPUT_INACTIVE);
}
return 0;
}
SYS_INIT(tx_led_init, APPLICATION, 90);
#endif
namespace mesh {
uint16_t ZephyrBoard::getBattMilliVolts()
@@ -142,6 +164,20 @@ const char *ZephyrBoard::getManufacturerName() const
return CONFIG_ZEPHCORE_BOARD_NAME;
}
void ZephyrBoard::onBeforeTransmit()
{
#if HAS_TX_LED
gpio_pin_set_dt(&tx_led, 1);
#endif
}
void ZephyrBoard::onAfterTransmit()
{
#if HAS_TX_LED
gpio_pin_set_dt(&tx_led, 0);
#endif
}
void ZephyrBoard::reboot()
{
k_msleep(50); /* Let UART/USB flush */
+2
View File
@@ -14,6 +14,8 @@ public:
uint16_t getBattMilliVolts() override;
float getMCUTemperature() override;
const char *getManufacturerName() const override;
void onBeforeTransmit() override;
void onAfterTransmit() override;
void reboot() override;
void rebootToBootloader(); /* Reboot into UF2 mass storage bootloader */
bool getBootloaderVersion(char *version, size_t max_len) override;
@@ -35,3 +35,7 @@ CONFIG_HEAP_MEM_POOL_SIZE=6144
# Shrink RTT buffer to free RAM (4096 → 1024, saves 3KB).
# Only used during J-Link debugging, 1KB is Zephyr's default.
CONFIG_SEGGER_RTT_BUFFER_SIZE_UP=1024
# RX duty cycle — safe on SX1262 (only LR1110 has mid-preamble issues).
# Extends battery life on this battery-powered board.
CONFIG_ZEPHCORE_LORA_RX_DUTY_CYCLE=y
@@ -45,6 +45,8 @@
lora0 = &lora;
led0 = &led_green;
led1 = &led_blue;
led2 = &lora_tx_led;
lora-tx-led = &lora_tx_led;
sw0 = &user_button;
watchdog0 = &wdt0;
buzzer = &buzzer;
@@ -64,6 +66,12 @@
gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
label = "Blue LED";
};
/* LoRa TX activity LED (active-high, matches Arduino P_LORA_TX_LED) */
lora_tx_led: led_2 {
gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
label = "TX LED";
};
/* LED_RED (P1.06) omitted — shared with display SPI MISO */
};
@@ -172,14 +180,14 @@
};
};
/* Display power enable (P1.11) — drives the EPD's boost converter /
* frontlight. Without this HIGH, SPI works but the charge pump
* cannot flip e-ink particles (display appears dead). */
/* Display backlight enable (P1.11) — powers the e-paper frontlight.
* The hardware knob dims brightness; this GPIO gates the circuit.
* Controlled dynamically by display.c (on with display, off on auto-off)
* so the backlight is fully off when not needed. */
disp_pwr_enable: disp-pwr-enable {
compatible = "regulator-fixed";
regulator-name = "disp-pwr-enable";
enable-gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>;
regulator-boot-on;
};
/* ---- E-Paper display (MIPI DBI SPI) ----
@@ -201,6 +209,7 @@
reg = <0>;
width = <200>;
height = <200>;
rotation = <270>;
busy-gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>;
};
};
+28 -2
View File
@@ -20,6 +20,7 @@
#include <zephyr/device.h>
#include <zephyr/display/cfb.h>
#include <zephyr/drivers/display.h>
#include <zephyr/drivers/regulator.h>
#include <zephyr/kernel.h>
#include <string.h>
#include <stdio.h>
@@ -40,6 +41,27 @@ static uint8_t font_w;
static uint8_t font_h;
static bool is_epd; /* true for e-paper displays */
/* Optional display backlight regulator (e.g. e-paper frontlight).
* Boards define a "disp_pwr_enable" regulator-fixed node to gate the
* backlight circuit. When present, backlight follows display on/off. */
#if DT_NODE_EXISTS(DT_NODELABEL(disp_pwr_enable))
static const struct device *backlight_reg =
DEVICE_DT_GET_OR_NULL(DT_NODELABEL(disp_pwr_enable));
#else
static const struct device *backlight_reg;
#endif
static inline void backlight_set(bool on)
{
if (backlight_reg && device_is_ready(backlight_reg)) {
if (on) {
regulator_enable(backlight_reg);
} else {
regulator_disable(backlight_reg);
}
}
}
/* Auto-off work */
static struct k_work_delayable auto_off_work;
@@ -50,9 +72,10 @@ static void auto_off_handler(struct k_work *work)
if (doom_game_is_running()) {
return;
}
/* E-paper uses zero power when static — blanking wastes a full
* refresh cycle (~2s) and leaves the screen blank for no benefit. */
/* E-paper content persists without power — blanking wastes a full
* refresh cycle (~2s) for no benefit. Just turn off the backlight. */
if (is_epd) {
backlight_set(false);
return;
}
if (disp_on) {
@@ -170,6 +193,7 @@ int mc_display_init(void)
cfb_framebuffer_finalize(disp_dev);
display_blanking_off(disp_dev);
backlight_set(true);
disp_on = true;
disp_initialized = true;
@@ -211,6 +235,7 @@ void mc_display_on(void)
display_blanking_off(disp_dev);
disp_on = true;
}
backlight_set(true);
mc_display_reset_auto_off();
}
@@ -223,6 +248,7 @@ void mc_display_off(void)
if (disp_on) {
display_blanking_on(disp_dev);
backlight_set(false);
disp_on = false;
}
}
+15 -2
View File
@@ -80,12 +80,15 @@ LOG_MODULE_REGISTER(ui_task, CONFIG_ZEPHCORE_BOARD_LOG_LEVEL);
/* Match Arduino: 4s cycle, 20ms pulse (normal) or 200ms (unread messages).
* Uses led0 or led1 alias — whichever exists in the board's DTS.
* Disabled when OLED display is present (display makes LED redundant). */
#if DT_NODE_HAS_PROP(DT_ALIAS(led0), gpios) && !IS_ENABLED(CONFIG_ZEPHCORE_UI_DISPLAY)
/* Heartbeat LED — subtle pulse every 4s on led0 (or led1 fallback).
* Works alongside displays; boards that want to disable it can
* remove the led0 alias or override this with a Kconfig guard. */
#if DT_NODE_HAS_PROP(DT_ALIAS(led0), gpios)
#define LED_NODE DT_ALIAS(led0)
static const struct gpio_dt_spec heartbeat_led =
GPIO_DT_SPEC_GET(LED_NODE, gpios);
#define HAS_HEARTBEAT_LED 1
#elif DT_NODE_HAS_PROP(DT_ALIAS(led1), gpios) && !IS_ENABLED(CONFIG_ZEPHCORE_UI_DISPLAY)
#elif DT_NODE_HAS_PROP(DT_ALIAS(led1), gpios)
#define LED_NODE DT_ALIAS(led1)
static const struct gpio_dt_spec heartbeat_led =
GPIO_DT_SPEC_GET(LED_NODE, gpios);
@@ -1035,5 +1038,15 @@ void ui_refresh_display(void)
return;
}
/* EPD displays: skip periodic housekeeping renders.
* Each full e-paper refresh takes ~2s and causes visible flashing.
* All meaningful events (messages, BLE, GPS fix, button presses)
* already trigger renders via their own ui_set_*() → schedule_render().
* Housekeeping just updates slow-changing data (clock, contact ages)
* which will appear on the next event-driven render. */
if (mc_display_is_epd()) {
return;
}
schedule_render();
}