Skip to content

[realtek-ambz2] lt_reboot() can hang RTL8720CF; sys_reset() works #396

Description

@ngorchilov

Summary

On physical Tuya WBR3 modules using RTL8720CF, ESPHome's software restart and the reboot after a
successful OTA update can leave the device offline until power is cycled. Calling the AMBZ2 SDK's
sys_reset() directly restarts the same hardware successfully without a power cycle.

The firmware uploaded over OTA is present and boots normally after the power cycle, so the OTA write
and image activation appear to complete successfully. The failure is in the final reboot operation.

Environment

  • LibreTiny: v1.13.0
  • ESPHome: 2026.7.0
  • Chip/module: RTL8720CF on physical Tuya WBR3 modules
  • ESPHome board profile: bw15

The modules were originally UART-flashed with the BW15/SDK-default 992 KiB partition layout before a
WBR3 board definition existed, so they must retain that board profile for OTA layout compatibility.
The reboot behavior has existed since the initial firmware and remains reproducible with the current
official LibreTiny release.

Reproduction

With a normal ESPHome restart button:

rtl87xx:
  board: bw15

button:
  - platform: restart
    name: Restart
  1. Boot the device normally.
  2. Press the restart button.
  3. The device goes offline and does not return.
  4. Power-cycle it; it boots normally.

The same thing happens after ESPHome reports a successful OTA upload. After a power cycle, the newly
uploaded firmware boots, confirming that the update itself was written and selected.

Diagnostic Test

This template button was tested on the same firmware and hardware:

button:
  - platform: template
    name: Full Restart Test
    on_press:
      - lambda: |-
          extern void realtek_system_reset(void) asm("sys_reset");
          realtek_system_reset();
          while (true) {}

Unlike the standard restart button, this restarts the module successfully without a power cycle.

Source Analysis

The current AMBZ2 implementation calls sys_cpu_reset():

void lt_reboot() {
    sys_cpu_reset();
    while (1) {}
}

Source:
https://github.com/libretiny-eu/libretiny/blob/master/cores/realtek-ambz2/base/api/lt_device.c

In the Realtek AMBZ2 SDK, sys_cpu_reset() performs a CPU reset after shutting down several
subsystems. sys_reset() disables fast boot and triggers a watchdog-based system reset. The latter
is the operation that works on this hardware.

There is a close precedent in issue #40. RTL8710BN devices showed the same software-restart and
post-OTA hang, and changing the reset path to sys_reset() fixed both:
#40

Proposed Fix

Would replacing sys_cpu_reset() with sys_reset() be appropriate for AMBZ2 as well?

 void lt_reboot() {
-    sys_cpu_reset();
+    sys_reset();
     while (1) {}
 }

I can test a patched build on three currently accessible RTL8720CF modules, including repeated
software restarts and consecutive OTA updates.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions