embassy-rs/embassy · error

Unknown USB core id

Error message

Unknown USB core id {:X}

What it means

embassy-stm32's OTG USB driver reads the core ID register during init and dispatches configuration by known Synopsys OTG core versions (v1.x, v2/v3, v5). If the hardware reports a core ID outside the known set, it panics with "Unknown USB core id". This means the chip's USB peripheral is not one of the OTG cores the driver recognizes.

Solutions

  1. Print/inspect the core_id value and compare against the known list (0x1000-0x1200, 0x2000-0x3100, 0x5000/0x6100)
  2. Update embassy-stm32 to the latest version; new core IDs are added as chips are validated
  3. Verify you are targeting the correct USB peripheral instance for your chip (OTG_HS vs OTG_FS vs USB) in your board support code
  4. File an upstream issue with your chip model and reported core id so the variant can be added

Example fix

// before: unknown core id panics in init
// after: assert the peripheral you bind is the right one
let usb = embassy_stm32::usb::UsbDevice::new(
    p.USB_OTG_FS, // correct instance for your chip
    vbus_detect, ep_out_buffer, config,
);
Defensive patterns

Strategy: validation

Validate before calling

// Verify your chip's OTG core id is in the supported set before enabling the usb driver
const KNOWN_CORE_IDS: [u32; 9] = [0x1200, 0x1100, 0x1000, 0x2000, 0x2100, 0x2300, 0x3000, 0x3100, 0x5000, 0x6100 - 1]; // see driver list
// On target, before driver init:
// let core_id = otg_global.gsnpsid().read().0;
// assert!(matches!(core_id, 0x0000_1000..=0x0000_1200 | 0x0000_2000..=0x0000_3100 | 0x0000_5000 | 0x0000_6100));

Try / catch

// Read GSNPSID early and panic with a diagnostic instead of the raw driver panic
let core_id = unsafe { pac::OTG_HS_GLOBAL.gsnpsid().read().0 };
assert!(core_id == 0x0000_5000 || core_id == 0x0000_6100, "unsupported OTG core id {:X}", core_id);

Prevention

When it happens

Trigger: Booting a USB application (Device or Host) on an STM32 whose OTG peripheral reports an unrecognized GSNPSID core-id value, causing the _ arm of the match in otg.rs init to panic.

Common situations: Running embassy on a new/rare STM32 variant (or a clone/simulated chip) whose OTG core revision isn't in the driver's known list; enabling the usb feature for a chip family not yet validated by embassy-stm32.

Understand the failure class

Background: "unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them — 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/7a4fe7cc8e374214. Report an issue: GitHub.

Appendix: source

Thrown at embassy-stm32/src/usb/otg.rs:405

            });
        }

        let r = T::regs();
        let core_id = r.cid().read().0;
        trace!("Core id {:08x}", core_id);

        // Wait for AHB ready.
        while !r.grstctl().read().ahbidl() {}

        // Configure as device.
        self.inner.configure_as_device();

        // Configuring Vbus sense and SOF output
        match core_id {
            0x0000_1200 | 0x0000_1100 | 0x0000_1000 => self.inner.config_v1(),
            0x0000_2000 | 0x0000_2100 | 0x0000_2300 | 0x0000_3000 | 0x0000_3100 => self.inner.config_v2v3(),
            0x0000_5000 | 0x0000_6100 => self.inner.config_v5(),
            _ => unimplemented!("Unknown USB core id {:X}", core_id),
        }
    }

    fn disable(&mut self) {
        if !self.inited {
            return;
        }

        T::Interrupt::disable();

        #[cfg(all(stm32wba, peri_usb_otg_hs))]
        {
            debug!("disabling OTG clocks");
            crate::pac::SYSCFG.otghsphycr().modify(|w| w.set_en(false));
            critical_section::with(|_| {
                crate::pac::RCC.ahb2enr().modify(|w| w.set_usb_otg_hs_phyen(false));
                crate::pac::PWR.vosr().modify(|w| {
                    w.set_usbboosten(false);

View on GitHub (pinned to 463a07b963)