embassy-rs/embassy · error

DTS PCLK frequency must be less than 127 MHz.

Error message

DTS PCLK frequency must be less than 127 MHz.

What it means

The DTS (digital temperature sensor) kernel clock must be slow enough that (freq / MAX_DTS_CLK_FREQ) fits in the 7-bit HSREF_CLK_DIV field (max 127). If the computed prescaler exceeds 127 the divider cannot be represented in the register and the driver panics.

Solutions

  1. Lower the DTS kernel clock in the RCC config so freq / MAX_DTS_CLK_FREQ <= 127.
  2. Add a divider or lower PCLK/system frequency for the DTS peripheral.
  3. Check rcc::frequency::<DTS>() before constructing the sensor.

Example fix

// before
cfg.dts_clock = None; // inherits fast PCLK
// after
cfg.dts_clock = Some(Hz(50_000_000)); // prescaler <= 127
Defensive patterns

Strategy: validation

Validate before calling

let dts_hz = embassy_stm32::rcc::frequency::<DTS>().0;
assert!(dts_hz / MAX_DTS_CLK_FREQ <= 127, "DTS kernel clock too high: {} Hz", dts_hz);

Prevention

When it happens

Trigger: Calling Dts::new() while the RCC-configured DTS/PCLK frequency makes prescaler = freq / MAX_DTS_CLK_FREQ > 127.

Common situations: High system/PCLK frequencies (250 MHz+) without a dedicated DTS kernel-clock divider; default RCC setups on H5/U5 boards.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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

Appendix: source

Thrown at embassy-stm32/src/dts/mod.rs:92

pub struct Dts<'d> {
    _peri: Peri<'d, DTS>,
}

static WAKER: AtomicWaker = AtomicWaker::new();

impl<'d> Dts<'d> {
    /// Create a new temperature sensor driver.
    pub fn new(
        _peri: Peri<'d, DTS>,
        _irq: impl interrupt::typelevel::Binding<interrupt::typelevel::DTS, InterruptHandler> + 'd,
        config: Config,
    ) -> Self {
        rcc::enable_and_reset::<DTS>();

        let prescaler = rcc::frequency::<DTS>() / MAX_DTS_CLK_FREQ;

        if prescaler > 127 {
            panic!("DTS PCLK frequency must be less than 127 MHz.");
        }

        Self::regs().cfgr1().modify(|w| {
            w.set_refclk_sel(false);
            w.set_hsref_clk_div(prescaler as u8);
            w.set_q_meas_opt(false);
            // Software trigger
            w.set_intrig_sel(0);
            w.set_smp_time(config.sample_time as u8);
            w.set_intrig_sel(config.trigger as u8);
            w.set_start(true);
            w.set_en(true);
        });

        interrupt::DTS.unpend();
        unsafe { interrupt::DTS.enable() };

        Self { _peri }

View on GitHub (pinned to 463a07b963)