{"record":{"id":"f3f934cf26e9083c","repo":"embassy-rs/embassy","slug":"mclk-frequency-9-5-mhz-is-not-compatible-with","errorCode":null,"errorMessage":"MCLK frequency {} < 9.5 MHz is not compatible with the TRNG","messagePattern":"MCLK frequency (.+?) < 9\\.5 MHz is not compatible with the TRNG","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"embassy-mspm0/src/trng.rs","lineNumber":358,"sourceCode":"    }\n\n    fn set_div(&mut self) {\n        // L-series TRM 13.2.2: The TRNG is derived from MCLK. Datasheets specify 9.5-20 MHz range.\n        let freq = crate::sysctl::mclk_frequency();\n        let ratio = if freq > 160_000_000 {\n            panic!(\"MCLK frequency {} > 160 MHz is not compatible with the TRNG\", freq)\n        } else if freq >= 80_000_000 {\n            Ratio::DivBy8\n        } else if freq >= 60_000_000 {\n            Ratio::DivBy6\n        } else if freq >= 40_000_000 {\n            Ratio::DivBy4\n        } else if freq >= 20_000_000 {\n            Ratio::DivBy2\n        } else if freq >= 9_500_000 {\n            Ratio::DivBy1\n        } else {\n            panic!(\"MCLK frequency {} < 9.5 MHz is not compatible with the TRNG\", freq)\n        };\n        regs().clkdiv().write(|w| w.set_ratio(ratio));\n    }\n\n    fn set_decim_rate(&mut self) {\n        regs().ctl().modify(|w| w.set_decim_rate(self.decim_rate));\n    }\n\n    fn clr_rdy(&mut self) {\n        regs().iclr().write(|w| w.set_irq_captured_rdy(true));\n    }\n\n    fn set_cmd(&mut self, cmd: vals::Cmd) {\n        regs().iclr().write(|w| w.set_irq_cmd_done(true));\n        regs().ctl().modify(|w| w.set_cmd(cmd));\n        while !regs().ris().read().irq_cmd_done() {}\n    }\n","sourceCodeStart":340,"sourceCodeEnd":376,"githubUrl":"https://github.com/embassy-rs/embassy/blob/463a07b963419a1bfe61d5d597c44acb810afb8b/embassy-mspm0/src/trng.rs#L340-L376","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (MCLK from default ~4MHz source)\nlet p = embassy_mspm0::init(Default::default());\nlet mut trng = Trng::new(p.TRNG, p.PAxx);\n// after (configure 80 MHz MCLK first)\nlet config = Config { ... }; // clock config yielding MCLK >= 20 MHz\nlet p = embassy_mspm0::init(config);\nassert!(mclk_hz() >= 9_500_000, \"MCLK too low for TRNG\");\nlet mut trng = Trng::new(p.TRNG, p.PAxx);","handlingStrategy":"validation","validationCode":"// Rust (no-std): assert before constructing the TRNG\nfn ensure_trng_clock_ok(mclk_hz: u32) {\n    assert!(mclk_hz >= 9_500_000, \"MCLK {} Hz too low for TRNG (min 9.5 MHz)\", mclk_hz);\n}\nensure_trng_clock_ok(clock_config.mclk_hz());","typeGuard":"// Rust: validate the frequency before any division\nfn is_trng_compatible(mclk_hz: u32) -> bool { mclk_hz >= 9_500_000 }\n\nif !is_trng_compatible(mclk_hz) { /* reconfigure clocks or skip TRNG */ }","tryCatchPattern":null,"preventionTips":["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."],"tags":["embedded","rust","trng","clock-config","panic"],"backgroundTag":"invalid-config-value","analyzedSha":"463a07b963419a1bfe61d5d597c44acb810afb8b","analyzedAt":"2026-09-10T13:38:26.660Z","contentChangedAt":"2026-09-10T13:38:26.660Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}