embassy-rs/embassy · error
MCLK frequency < 9.5 MHz is not compatible with the TRNG
Error message
MCLK frequency {} < 9.5 MHz is not compatible with the TRNG What it means
The TRNG driver's clock setup (set_div, called from init) requires the MCLK system clock to be at least 9.5 MHz; below that no valid divider ratio exists, so the driver panics. The library throws this because the TRNG peripheral cannot operate reliably (sampling/decimation constraints) below its minimum input frequency. It is a compile-time-unknowable configuration constraint that can only be validated at runtime.
Solutions
- Raise MCLK to at least 9.5 MHz (e.g. 20/40/80 MHz from PLL) before constructing/initializing the TRNG.
- Call set_div only with freq >= 9_500_000; assert the clock frequency in your own init code before touching the TRNG.
- If low power is required, temporarily boost MCLK only when random data is needed, then re-derive entropy asynchronously.
- Check the ClockConfig passed to your RCC/clock setup and confirm the MCLK divider yields >= 9.5 MHz.
Example fix
// before (MCLK from default ~4MHz source)
let p = embassy_mspm0::init(Default::default());
let mut trng = Trng::new(p.TRNG, p.PAxx);
// after (configure 80 MHz MCLK first)
let config = Config { ... }; // clock config yielding MCLK >= 20 MHz
let p = embassy_mspm0::init(config);
assert!(mclk_hz() >= 9_500_000, "MCLK too low for TRNG");
let mut trng = Trng::new(p.TRNG, p.PAxx); Defensive patterns
Strategy: validation
Validate before calling
// Rust (no-std): assert before constructing the TRNG
fn ensure_trng_clock_ok(mclk_hz: u32) {
assert!(mclk_hz >= 9_500_000, "MCLK {} Hz too low for TRNG (min 9.5 MHz)", mclk_hz);
}
ensure_trng_clock_ok(clock_config.mclk_hz()); Type guard
// Rust: validate the frequency before any division
fn is_trng_compatible(mclk_hz: u32) -> bool { mclk_hz >= 9_500_000 }
if !is_trng_compatible(mclk_hz) { /* reconfigure clocks or skip TRNG */ } Prevention
- Always configure the high-speed clock (PLL) before initializing peripherals with minimum-frequency requirements.
- Centralize the MCLK frequency in a constant and add a static/const assertion against all peripheral minimums.
- Re-verify clock config after any low-power mode changes that alter MCLK.
- Review the datasheet TRNG requirements when changing clock trees.
When it happens
Trigger: Calling embassy_mspm0::trng::Trng::init (which calls set_div) while MCLK is configured below 9,500,000 Hz — e.g. running the MCU from a low-power clock configuration (default ~4 MHz or 32.768 kHz) instead of the full-speed PLL/DFLL setup.
Common situations: Developers using a minimal clock_init / default power-on clock tree before initializing the TRNG; low-power applications that drop MCLK below 9.5 MHz and later need random numbers; boards where the clock config was changed for power reasons but the TRNG min-frequency requirement was overlooked.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- must not select PLL source as DISABLE
- IC source was set to PLL , but it is not currently enabled
- LSE frequency more than 5% off from 32.768 kHz, cannot use…
- MSIx auto-calibration is enabled for a source that has not…
- LSE frequency more than 5% off from 32.768 kHz, cannot use…
AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10).
Data as JSON: /api/errors/f3f934cf26e9083c.
Report an issue: GitHub.
Appendix: source
Thrown at embassy-mspm0/src/trng.rs:358
}
fn set_div(&mut self) {
// L-series TRM 13.2.2: The TRNG is derived from MCLK. Datasheets specify 9.5-20 MHz range.
let freq = crate::sysctl::mclk_frequency();
let ratio = if freq > 160_000_000 {
panic!("MCLK frequency {} > 160 MHz is not compatible with the TRNG", freq)
} else if freq >= 80_000_000 {
Ratio::DivBy8
} else if freq >= 60_000_000 {
Ratio::DivBy6
} else if freq >= 40_000_000 {
Ratio::DivBy4
} else if freq >= 20_000_000 {
Ratio::DivBy2
} else if freq >= 9_500_000 {
Ratio::DivBy1
} else {
panic!("MCLK frequency {} < 9.5 MHz is not compatible with the TRNG", freq)
};
regs().clkdiv().write(|w| w.set_ratio(ratio));
}
fn set_decim_rate(&mut self) {
regs().ctl().modify(|w| w.set_decim_rate(self.decim_rate));
}
fn clr_rdy(&mut self) {
regs().iclr().write(|w| w.set_irq_captured_rdy(true));
}
fn set_cmd(&mut self, cmd: vals::Cmd) {
regs().iclr().write(|w| w.set_irq_cmd_done(true));
regs().ctl().modify(|w| w.set_cmd(cmd));
while !regs().ris().read().irq_cmd_done() {}
}
View on GitHub (pinned to 463a07b963)