mirror of
https://github.com/liquidraver/ZephCore.git
synced 2026-10-15 16:20:01 +00:00
leds: do not reclaim a PWM-shared pin as plain GPIO in main()
server_main_common.cpp and main_observer.cpp both configured led0 as a plain GPIO output at boot, unconditionally. On ESP32 that calls esp_rom_gpio_matrix_out() under the hood, which routes the pin's output to the GPIO signal and takes it away from whatever peripheral had it before, including the LEDC channel a heartbeat-pwm-led or lora-tx-pwm-led alias had already claimed during the PWM driver's own init. The PWM write then succeeds (no error, no warning) but never reaches the pin: confirmed on V4.3 hardware, where the same pin lights up fine over plain GPIO, and over PWM in a different (non-Zephyr) firmware, but stays dark over Zephyr's PWM once this GPIO configure has run. Companion builds never hit this (they don't use server_main_common.cpp) and nRF52 isn't affected (no shared GPIO matrix), which is why T096 tested fine while V4.3 didn't. Fix is alias-based, not a board list, so any future board with either PWM alias is covered without extra wiring. Also: CLI_HAS_RADIO_LED only checked the plain lora-tx-led alias, so "set leds.radio" replied "(no radio LED on this board)" on boards whose radio LED exists only via lora-tx-pwm-led (V4.3). Check both. Documents the two PWM aliases in the board porting guide, and leds.brightness plus the corrected LED topology counts in docs/CLI_commands.md. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
e5e927e530
commit
6b9d205b00
@@ -44,7 +44,15 @@ LOG_MODULE_REGISTER(zephcore_observer_main, CONFIG_ZEPHCORE_MAIN_LOG_LEVEL);
|
||||
|
||||
/* ========== LED (optional) ========== */
|
||||
|
||||
#if DT_NODE_HAS_PROP(DT_ALIAS(led0), gpios)
|
||||
/* True when a board aliases its heartbeat or TX-activity LED to a PWM node.
|
||||
* On ESP32, configuring led0 as plain GPIO after the PWM driver has already
|
||||
* routed the pin takes the pin back from the LEDC peripheral (the GPIO
|
||||
* matrix only serves one signal at a time), so on those boards led0 must be
|
||||
* left to the PWM driver instead of reconfigured here. */
|
||||
#define ZEPHCORE_HAS_PWM_SHARED_LED \
|
||||
(DT_NODE_EXISTS(DT_ALIAS(heartbeat_pwm_led)) || DT_NODE_EXISTS(DT_ALIAS(lora_tx_pwm_led)))
|
||||
|
||||
#if DT_NODE_HAS_PROP(DT_ALIAS(led0), gpios) && !ZEPHCORE_HAS_PWM_SHARED_LED
|
||||
#include <zephyr/drivers/gpio.h>
|
||||
#define LED0_NODE DT_ALIAS(led0)
|
||||
static const struct gpio_dt_spec led0 = GPIO_DT_SPEC_GET(LED0_NODE, gpios);
|
||||
@@ -320,7 +328,7 @@ int main(void)
|
||||
LOG_INF("=== ZephCore Observer starting ===");
|
||||
|
||||
/* Configure LED */
|
||||
#if DT_NODE_HAS_PROP(DT_ALIAS(led0), gpios)
|
||||
#if DT_NODE_HAS_PROP(DT_ALIAS(led0), gpios) && !ZEPHCORE_HAS_PWM_SHARED_LED
|
||||
if (gpio_is_ready_dt(&led0)) {
|
||||
gpio_pin_configure_dt(&led0, GPIO_OUTPUT_INACTIVE);
|
||||
}
|
||||
|
||||
@@ -142,6 +142,7 @@ Only `lora0` is required. Everything else enables its feature by being present.
|
||||
| `lfs_partition` + `filesystem.dtsi` | `/lfs`: identity, prefs, contacts, channels |
|
||||
| chosen `zephyr,settings-partition` | NVS for BLE bonds (nRF52, ESP32). nRF54L and MG24 keep bonds in a file on `/lfs` |
|
||||
| aliases `led0`, `led1`, `lora-tx-led` | Heartbeat, unread, TX blink |
|
||||
| aliases `heartbeat-pwm-led`, `lora-tx-pwm-led` | Same heartbeat/TX blink, brightness-adjustable (`leds.brightness`). Point both at one `pwm-leds` node to share a single physical LED. On ESP32, leave `led0`/`led1` out of the board's `main()` GPIO setup when either alias is present: configuring the same pin as plain GPIO after the PWM driver has claimed it takes the pin back from the LEDC peripheral (`ZEPHCORE_HAS_PWM_SHARED_LED` in `src/server_main_common.cpp` and `app/main_observer.cpp` already skips this for you) |
|
||||
| alias `sw0` | User button; wake source from nRF System OFF and ESP32 light sleep |
|
||||
| chosen `zephyr,display` | Display UI |
|
||||
| node labelled `buzzer` + alias `buzzer` | PWM buzzer |
|
||||
|
||||
@@ -65,6 +65,9 @@
|
||||
* led0 heartbeat LED
|
||||
* led1 second LED (unread messages on a companion)
|
||||
* lora-tx-led blinks while transmitting
|
||||
* heartbeat-pwm-led, lora-tx-pwm-led
|
||||
* same two roles, brightness-adjustable (leds.brightness);
|
||||
* point both at one pwm-leds node to share a physical LED
|
||||
* sw0 user button; also the wake source from nRF System OFF
|
||||
* and from ESP32 light sleep
|
||||
* buzzer PWM buzzer (the node must also be LABELLED buzzer)
|
||||
@@ -604,6 +607,51 @@ zephyr_udc0: &usbd {
|
||||
};
|
||||
#endif
|
||||
|
||||
#if 0 /* ---- Heartbeat/TX LED, brightness-adjustable (heltec_t096, heltec_wifi_lora32_v43) ----
|
||||
* One physical LED standing in for both led0 and lora-tx-led, but wired
|
||||
* through a pwm-leds node instead of gpio-leds so leds.brightness can
|
||||
* dim it. Point heartbeat-pwm-led and lora-tx-pwm-led at the same node
|
||||
* to share it, same as the plain-GPIO led0/lora-tx-led pair above.
|
||||
*
|
||||
* ESP32 only: also declare a plain led0 (gpio-leds) for this pin if the
|
||||
* board wants one, but do NOT add GPIO setup for it in the board's
|
||||
* main() -- src/server_main_common.cpp and app/main_observer.cpp skip
|
||||
* that already (ZEPHCORE_HAS_PWM_SHARED_LED) when either PWM alias is
|
||||
* present, because on ESP32 configuring the pin as plain GPIO after
|
||||
* the PWM driver has claimed it takes the pin back from the LEDC
|
||||
* peripheral: the GPIO matrix only routes one signal to a pin at a
|
||||
* time. nRF52 PWM and GPIO don't share hardware that way, so this does
|
||||
* not apply there. */
|
||||
/ {
|
||||
aliases {
|
||||
heartbeat-pwm-led = &pwm_led_white;
|
||||
lora-tx-pwm-led = &pwm_led_white;
|
||||
};
|
||||
|
||||
pwmleds {
|
||||
compatible = "pwm-leds";
|
||||
|
||||
pwm_led_white: pwm_led_0 {
|
||||
pwms = <&ledc0 0 PWM_MSEC(10) PWM_POLARITY_NORMAL>;
|
||||
label = "White PWM LED";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&ledc0 {
|
||||
status = "okay";
|
||||
pinctrl-0 = <&ledc0_default>;
|
||||
pinctrl-names = "default";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
channel0@0 {
|
||||
reg = <0x0>;
|
||||
timer = <0>;
|
||||
};
|
||||
};
|
||||
#endif
|
||||
|
||||
#if 0 /* ---- Battery voltage (rak4631) ----
|
||||
*
|
||||
* mV = raw * vbat-mv-multiplier / 4096, so the multiplier is the ADC's
|
||||
|
||||
@@ -68,9 +68,11 @@ static const NodePrefs* cliDefaults() {
|
||||
/* ---- leds.radio / leds.hb mode names ----------------------------------- */
|
||||
/*
|
||||
* Which LEDs this board has, so the CLI can say when a setting it stored
|
||||
* does nothing here. Mirrors the aliases the drivers use.
|
||||
* does nothing here. Mirrors the aliases the drivers use: lora-tx-led or
|
||||
* lora-tx-pwm-led, led0 with an led1 fallback.
|
||||
*/
|
||||
#define CLI_HAS_RADIO_LED DT_NODE_EXISTS(DT_ALIAS(lora_tx_led))
|
||||
#define CLI_HAS_RADIO_LED (DT_NODE_EXISTS(DT_ALIAS(lora_tx_led)) || \
|
||||
DT_NODE_EXISTS(DT_ALIAS(lora_tx_pwm_led)))
|
||||
#define CLI_HAS_HB_LED (DT_NODE_HAS_PROP(DT_ALIAS(led0), gpios) || \
|
||||
DT_NODE_HAS_PROP(DT_ALIAS(led1), gpios))
|
||||
|
||||
|
||||
@@ -71,8 +71,16 @@ extern "C" void bt_ctlr_assert_handle(char *file, uint32_t line)
|
||||
#include "wifi_ota.h"
|
||||
#endif
|
||||
|
||||
/* True when a board aliases its heartbeat or TX-activity LED to a PWM node.
|
||||
* On ESP32, configuring led0 as plain GPIO after the PWM driver has already
|
||||
* routed the pin takes the pin back from the LEDC peripheral (the GPIO
|
||||
* matrix only serves one signal at a time), so on those boards led0 must be
|
||||
* left to the PWM driver instead of reconfigured here. */
|
||||
#define ZEPHCORE_HAS_PWM_SHARED_LED \
|
||||
(DT_NODE_EXISTS(DT_ALIAS(heartbeat_pwm_led)) || DT_NODE_EXISTS(DT_ALIAS(lora_tx_pwm_led)))
|
||||
|
||||
/* LED configuration */
|
||||
#if DT_NODE_HAS_PROP(DT_ALIAS(led0), gpios)
|
||||
#if DT_NODE_HAS_PROP(DT_ALIAS(led0), gpios) && !ZEPHCORE_HAS_PWM_SHARED_LED
|
||||
#define LED0_NODE DT_ALIAS(led0)
|
||||
static const struct gpio_dt_spec led0 = GPIO_DT_SPEC_GET(LED0_NODE, gpios);
|
||||
#endif
|
||||
@@ -610,7 +618,7 @@ int server_main(const ServerRole &role)
|
||||
#endif
|
||||
|
||||
/* Configure LEDs */
|
||||
#if DT_NODE_HAS_PROP(DT_ALIAS(led0), gpios)
|
||||
#if DT_NODE_HAS_PROP(DT_ALIAS(led0), gpios) && !ZEPHCORE_HAS_PWM_SHARED_LED
|
||||
if (gpio_is_ready_dt(&led0)) {
|
||||
gpio_pin_configure_dt(&led0, GPIO_OUTPUT_INACTIVE);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user