embassy-rs/embassy · error

PKA initialization failed

Error message

PKA initialization failed

What it means

Pka::new_inner (the blocking constructor path) runs ensure_init_blocking() and unwraps the Result with expect("PKA initialization failed"). Init includes enabling clocks, resetting the accelerator, enabling the interrupt, and checking the PKA's mode; failure (Err from hardware init) is escalated to a panic at construction time instead of being returned to the caller.

Solutions

  1. Check the returned error by calling ensure_init_blocking-style init yourself or use a constructor variant returning Result, so you can log the real cause.
  2. Verify the PKA kernel clock is enabled in RCC before constructing the driver.
  3. Confirm the chip's PKA mode is supported by the driver (limited-mode chips are rejected by an assert in with_pka); use a supported variant or software crypto for unsupported ops.
  4. Perform a full peripheral reset (RCC reset + power-up sequence) before init if the hardware was left in a bad state.

Example fix

// before
let pka = Pka::new_blocking(p.PKA, Irqs); // panics on init failure

// after
match pka_init(&mut p.PKA, Irqs) { // API that surfaces the Result
    Ok(pka) => info!("PKA ready"),
    Err(e) => defmt::error!("PKA init failed: {:?}", e),
}
Defensive patterns

Strategy: validation

Validate before calling

// Before constructing PKA, ensure clocks and supported mode:
// RCC: enable PKA kernel clock; check chip variant is not limited-mode-only
// If a Result-returning init exists, use it instead of the panicking constructor.

Try / catch

// Prefer an API variant that returns Result over new_inner's expect, when available:
match pka.ensure_init_blocking() {
    Ok(_) => info!("pka init ok"),
    Err(e) => defmt::error!("pka init failed: {:?}", e),
}

Prevention

When it happens

Trigger: Constructing the PKA (via new/new_blocking leading to new_inner) when the underlying hardware init returns Err — e.g. PKA IP in an unexpected state, restricted/limited mode detected where unsupported, or reset/enable sequence failing on the given chip revision.

Common situations: Using a chip variant whose PKA is limited-mode (ECDSA-verify only) with a driver build expecting full mode; enabling the peripheral before its kernel clock is configured; silicon in a bad state after a warm reset without a proper PKA reset sequence.

Related errors


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

Appendix: source

Thrown at embassy-stm32/src/pka/mod.rs:840

    const RAM_ERASE_TIMEOUT: u32 = 100_000;

    /// The value the engine leaves in a result or error word to report success.
    #[cfg(not(pka_v1c))]
    const SUCCESS: u32 = 0xD60D;
    #[cfg(pka_v1c)]
    const SUCCESS: u32 = 0;

    fn new_inner(peripheral: Peri<'d, T>) -> Self {
        rcc::enable_and_reset::<T>();

        T::Interrupt::unpend();
        unsafe { T::Interrupt::enable() };

        let mut s = Self {
            _peripheral: peripheral,
            _marker: PhantomData,
        };
        s.ensure_init_blocking().expect("PKA initialization failed");
        s
    }

    // ========================================================================
    // ECDSA Operations
    // ========================================================================

    fn prepare_ecdsa_verify(
        &mut self,
        curve: &EcdsaCurveParams,
        public_key: &EcdsaPublicKey,
        signature: &EcdsaSignature,
        message_hash: &[u8],
    ) -> Result<(), Error> {
        let modulus_size = curve.p_modulus.len();
        let order_size = curve.order.len();

        // Validate sizes

View on GitHub (pinned to 463a07b963)