embassy-rs/embassy · error

unrecognized rx error

Error message

unrecognized rx error

What it means

When an RX interrupt/status error fires on LPC55 USART, embassy-nxp maps each known status flag (parity, noise, overrun) to an Error variant. If none of the checked flags explains the interrupt, the driver has no mapping and hits `unreachable!`, meaning an unexpected/unhandled hardware error condition occurred.

Solutions

  1. Update embassy-nxp to the latest version; the flag mapping may have been extended.
  2. Check the periphq/fifointstat registers at the failure point and file an issue with the register values if no known flag is set.
  3. Ensure error interrupts are enabled/expected only for the conditions the driver handles (parity, noise, overrun).
  4. As a workaround, guard reads so the error path is only taken when a mapped flag is known to be set.
Defensive patterns

Strategy: try-catch

Try / catch

// Panics are not catchable in embedded Rust; keep the read call isolated so a
// panic cannot take down unrelated subsystems, and log before reading:
match uart.read(&mut buf) {
    Ok(n) => handle(n),
    Err(e) => log::error!("usart rx error: {:?}", e),
}

Prevention

When it happens

Trigger: The USART error interrupt fires but `parityint` in INTSTAT and `rxerr` in FIFOINTSTAT are all clear, so the exhaustive if/else-if chain in `read()` falls through to `unreachable!`.

Common situations: Reading on a UART whose error interrupt was raised by a condition this driver version does not classify (e.g. a chip-variant-specific flag or spurious interrupt after FIFO reset); running on hardware/revision not covered by the driver's flag mapping.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10). Data as JSON: /api/errors/cbe80fb396838eb1. Report an issue: GitHub.

Appendix: source

Thrown at embassy-nxp/src/usart/lpc55.rs:412

            }
        };

        // If we got no error, just return at this point
        if !errors {
            return Ok(());
        }

        // If we DID get an error, we need to figure out which one it was.
        if self.info.usart_reg.intstat().read().framerrint() {
            return Err(Error::Framing);
        } else if self.info.usart_reg.intstat().read().parityerrint() {
            return Err(Error::Parity);
        } else if self.info.usart_reg.intstat().read().rxnoiseint() {
            return Err(Error::Noise);
        } else if self.info.usart_reg.fifointstat().read().rxerr() {
            return Err(Error::Overrun);
        }
        unreachable!("unrecognized rx error");
    }
}

impl<'d> Usart<'d, Blocking> {
    pub fn new_blocking<T: Instance>(
        usart: Peri<'d, T>,
        tx: Peri<'d, impl TxPin<T>>,
        rx: Peri<'d, impl RxPin<T>>,
        config: Config,
    ) -> Self {
        let tx_func = tx.pin_func();
        let rx_func = rx.pin_func();

        Self::new_inner(usart, tx.into(), tx_func, rx.into(), rx_func, false, None, None, config)
    }
}

impl<'d> Usart<'d, Async> {

View on GitHub (pinned to 463a07b963)