Skip to content

Serial refactor may break UART RX on realtek-ambz — init order reversed #366

Description

@swoboda1337

Reported downstream at esphome/esphome#14312 — modbus commands time out on RTL8710BN since the libretiny bump from v1.10.0 to v1.12.1. TX works fine but RX never receives data. User confirmed v1.10.0 works and v1.12.1 doesnt.

The Serial library refactor split begin() into beginPrivate() + configure(). Looking at the code I think this may have reversed the initialization order relative to what the Realtek SDK documents. Havent been able to test this on hardware so this is just code analysis.

Realtek SDK documented order (from rtl8711b_uart.h):

4. UART_Init()         — frame format
5. UART_SetBaud()      — baud rate
6. UART_INTConfig()    — enable IRQ
7. UART_RxCmd()        — enable RX path

Old code (v1.10.0) — followed SDK order:

configure()  → UART_Init() + UART_SetBaud()
VECTOR_IrqRegister/IrqEn
UART_RxCmd(ENABLE)
UART_INTConfig(RUART_IER_ERBI, ENABLE)

New code (v1.12.1) — reversed:

beginPrivate():
  VECTOR_IrqRegister/IrqEn
  UART_RxCmd(ENABLE)              ← RX enabled first
  UART_INTConfig(ERBI, ENABLE)    ← IRQ enabled first
configure():
  UART_Init()                     ← frame format AFTER
  UART_SetBaud()                  ← baud rate AFTER

The call chain is in cores/common/arduino/libraries/api/Serial/Serial.cpp:

void SerialClass::begin(unsigned long baudrate, uint16_t config, pin_size_t rx, pin_size_t tx) {
    this->end();
    if (!this->setPins(rx, tx))
        return;
    if (!this->data) {
        this->data  = new SerialData();
        this->rxBuf = new SerialRingBuffer();
    }
    this->beginPrivate(baudrate, config);  // sets up IRQ + RX
    this->configure(baudrate, config);     // then calls UART_Init + SetBaud
}

UART_Init() is a ROM function so cant inspect it directly. The theory is that if it resets the RX path or IER register as part of peripheral init, then RX would be dead after configure() runs. TX would still work because its polled, not interrupt-driven. This would match the reported symptom of modbus commands being sent but responses never arriving.

Could also be something else entirely in the refactor thats causing it — this is just the most suspicious change I found from reading the code.

Board: generic-rtl8710bx-4mb-980k (RTL8710BN)
Working: libretiny v1.10.0
Broken: libretiny v1.12.1

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