Skip to content

[lightning-ln882h] Change default log output port to UART1#373

Open
Bl00d-B0b wants to merge 1 commit intolibretiny-eu:masterfrom
Bl00d-B0b:fix/ln882h-uart0-pin-claim-when-silent
Open

[lightning-ln882h] Change default log output port to UART1#373
Bl00d-B0b wants to merge 1 commit intolibretiny-eu:masterfrom
Bl00d-B0b:fix/ln882h-uart0-pin-claim-when-silent

Conversation

@Bl00d-B0b
Copy link
Copy Markdown

Problem

On LN882H, lt_init_log() unconditionally calls serial_init() during startup, which triggers uart_io_pin_request() → sets the AFIO pin mux for the default UART port's TX/RX pins. This permanently claims those pins (e.g. PA2/PA3 for UART0) even when logger: baud_rate: 0 is set in ESPHome, preventing them from being used as GPIO.

On BK72XX this is not an issue because UART0 is pre-initialized by the Beken bootloader — LibreTiny never claims it explicitly.

Root cause

// lt_init.c — always runs, regardless of logger settings
static void lt_init_log(void) {
    uart_print_port = LT_UART_DEFAULT_LOGGER;
    serial_init(&m_LogSerial, LT_UART_DEFAULT_PORT, CFG_UART_BAUDRATE_LOG, NULL);
    //           ^^^ calls uart_io_pin_request() → AFIO claims PA2/PA3
}

Fix

When LT_UART_SILENT_ALL=1 (set by ESPHome's sdk_silent: all, which is the default), all SDK UART output is already suppressed via printf_config.h — the logger serial is never written to. Skipping serial_init() in this case is safe and frees the UART pins for GPIO use.

When serial output is actually needed, ESPHome's logger component or an explicit Serial.begin() call initializes the hardware instead.

Effect

With this fix, setting logger: baud_rate: 0 in ESPHome (combined with the default sdk_silent: all) frees the default UART TX/RX pins for GPIO use on LN882H — consistent with BK72XX behaviour.

Without the fix, users must work around this by setting LT_UART_DEFAULT_PORT: 1 in their ESPHome config to redirect the logger to a different UART port.

Bl00d-B0b added a commit to Bl00d-B0b/libretiny that referenced this pull request Apr 2, 2026
…ibretiny-eu#373)

When LT_UART_SILENT_ALL=1 (set by ESPHome's sdk_silent: all, which is
the default), all SDK UART output is suppressed via printf_config.h so
the SDK logger serial is never written to. Skipping serial_init() in
this case prevents the default UART port from claiming its TX/RX pins
via AFIO, allowing them to be used as GPIO.

On BK72XX this is not an issue because UART0 is pre-initialized by the
Beken bootloader. On LN882H, UART0 is initialized explicitly by
lt_init_log(), unconditionally claiming PA2/PA3 even when logger:
baud_rate: 0 is set in ESPHome.

When serial output is actually needed, ESPHome's logger component or
an explicit Serial.begin() call will initialize the hardware.
@Bl00d-B0b Bl00d-B0b force-pushed the fix/ln882h-uart0-pin-claim-when-silent branch from fc3046c to 8414c94 Compare April 2, 2026 19:17
@Bl00d-B0b Bl00d-B0b changed the title [ln882h] Skip UART serial_init when all output is silenced [lightning-ln882h] Skip UART serial_init when all output is silenced Apr 2, 2026
@kuba2k2
Copy link
Copy Markdown
Member

kuba2k2 commented Apr 3, 2026

The LT_UART_SILENT_ALL doesn't apply to LT logger, but only to vendor SDK logging (using printf()). Initializing the UART shouldn't be disabled based on that configuration option, because it serves a different purpose. See: documentation.

A better solution would be to use the LT_LOGGER flag. This allows to disable the LT logger output entirely, but currently the UART is still initialized. Making the initialization conditional on this flag would indeed free the UART TX/RX pins from the logger.

There is however another component that uses UART internally in LT - Auto-download-reboot. When it's enabled (the default option), it listens for flashing commands on the default flashing port (depends on the chip). To do that, it needs to initialize the UART. The LT_AUTO_DOWNLOAD_REBOOT flag is enabled by default, but it's currently not implemented on LN882, so it doesn't make a difference anyway.


Note that, on most off-the-shelf devices, the UART used for log output is usually not connected to any other peripherals. Because of this I don't really see the purpose of using these pins for anything else, unless you're using some kind of development board, or have unsoldered the module and use it as a bare module.

@Bl00d-B0b
Copy link
Copy Markdown
Author

Bl00d-B0b commented Apr 5, 2026

Thanks for the detailed explanation, that makes sense.

Real-world context: Just to address the skepticism — this is not a dev board or bare module. The device is a DS-101JL dual-gang wall switch. The MCU module is an LN-CB3S V1.0 — a pin-compatible drop-in replacement for the Tuya CB3S (Beken BK7231N) module, but carrying a WL2H-U-2 chip (Tuya's Lightning Semi LN882H variant) instead. Because it reuses the CB3S footprint on a mass-produced PCB, PA2 is physically connected to the right indicator LED on the switch.

LN-CB3S V1.0 board with WL2H-U-2 module


Reworked: I've updated the PR to use the correct fix — changing lt_family.h to prefer UART1 over UART0 as the default log port, consistent with how beken-72xx avoids UART0. The lt_init.c conditional has been reverted entirely. This matches the Tuya WL2H-U datasheet and fixes the root cause introduced in #312 for all LN882H boards, not just boards with LT_UART_SILENT_ALL.

@kuba2k2
Copy link
Copy Markdown
Member

kuba2k2 commented Apr 5, 2026

when ESPHome's logger: baud_rate: 0 is configured, does that currently map to LT_LOGGER=0 in LibreTiny?

No, it doesn't. baud_rate: 0 only causes ESPHome to initialize the Serial instance (which is already initialized by the logger), and to disable the Serial.println() operations completely.

My understanding is it sets LT_UART_SILENT_ALL=1 [...]

It doesn't either. This is a separate option, controlled by ESPHome's sdk_silent: option.

would a combined condition like !LT_LOGGER || LT_UART_DEFAULT_PORT != 0 be more appropriate

LT_UART_DEFAULT_PORT can have a valid value of 0 - this is the UART index, which on LN882x can be UART0, 1 or 2 (depending on available board pins).


Disabling the UART initialization on !LT_LOGGER is definitely a valid fix to implement, but it won't fix your issues entirely.

Your device's LED is connected to GPIOA2, which is also the UART0 TX pin. On the LN-CB3S module, it's available on pad 16 - which corresponds to all other CB3S-like modules (or even ESP12F modules). On all prior Beken-based boards this port was NOT used for the logging output.

Per Tuya documentation on WL2H-U, this also applies to LN882x modules - the correct logging output port is UART1, not UART0.

Your device was designed with this in mind - the original firmware was most definitely using UART1, so the UART0 port was free to use as the LED indicator.


The real solution would probably be to change the default logging port of LibreTiny to UART1 - we usually try to stick to the manufacturer-defined UART usage conventions. The LN882H support was added in PR #312, and apparently it was just implemented incorrectly for this whole time.

Per Tuya WL2H-U datasheet, UART1 (PB8/PB9) is the designated log output
port on LN882H modules. UART0 (PA2/PA3) is the user UART and is typically
connected to GPIOs on CB3S-footprint boards (e.g. indicator LEDs on the
DS-101JL wall switch). Using UART0 as the default log port was introduced
in libretiny-eu#312 and caused PA2/PA3 to be claimed by AFIO, preventing their use
as GPIO.

Change lt_family.h to prefer UART1 over UART0 as the default, consistent
with how beken-72xx defaults to UART2/UART1 and avoids UART0.
@Bl00d-B0b Bl00d-B0b force-pushed the fix/ln882h-uart0-pin-claim-when-silent branch from 2342bb2 to 0e9b9b5 Compare April 7, 2026 06:11
Bl00d-B0b added a commit to Bl00d-B0b/libretiny that referenced this pull request Apr 7, 2026
Per Tuya WL2H-U datasheet, UART1 (PB8/PB9) is the designated log output
port on LN882H modules. UART0 (PA2/PA3) is the user UART and is typically
connected to GPIOs on CB3S-footprint boards (e.g. indicator LEDs on the
DS-101JL wall switch). Using UART0 as the default log port was introduced
in libretiny-eu#312 and caused PA2/PA3 to be claimed by AFIO, preventing their use
as GPIO.

Change lt_family.h to prefer UART1 over UART0 as the default, consistent
with how beken-72xx defaults to UART2/UART1 and avoids UART0.
@Bl00d-B0b
Copy link
Copy Markdown
Author

Thanks for digging into the root cause — you're right, the correct fix is much simpler. I've reworked the PR: lt_family.h now prefers UART1 over UART0 as the default log port (mirroring how beken-72xx avoids UART0), and the lt_init.c conditional has been reverted entirely. This fixes the issue at the source for all LN882H boards rather than working around it per-config.

@kuba2k2 kuba2k2 changed the title [lightning-ln882h] Skip UART serial_init when all output is silenced [lightning-ln882h] Change default log output port to UART1 Apr 8, 2026
@kuba2k2 kuba2k2 added bug Something isn't working enhancement New feature or request LN882H Lightning LN882H family labels Apr 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working enhancement New feature or request LN882H Lightning LN882H family

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants