{"record":{"id":"5fd180a276b4452d","repo":"embassy-rs/embassy","slug":"requested-divider-is-too-large","errorCode":null,"errorMessage":"Requested divider is too large","messagePattern":"Requested divider is too large","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"embassy-rp/src/pwm.rs","lineNumber":255,"sourceCode":"    ) -> Self {\n        Self::new_inner(\n            slice.number(),\n            Some(a.into()),\n            Some(b.into()),\n            b_pull,\n            config,\n            mode.into(),\n        )\n    }\n\n    /// Set the PWM config.\n    pub fn set_config(&mut self, config: &Config) {\n        Self::configure(pac::PWM.ch(self.slice), config);\n    }\n\n    fn configure(p: pac::pwm::Channel, config: &Config) {\n        if config.divider > FixedU16::<fixed::types::extra::U4>::from_bits(0xFFF) {\n            panic!(\"Requested divider is too large\");\n        }\n\n        p.div().write_value(ChDiv(config.divider.to_bits() as u32));\n        p.cc().write(|w| {\n            w.set_a(config.compare_a);\n            w.set_b(config.compare_b);\n        });\n        p.top().write(|w| w.set_top(config.top));\n        p.csr().modify(|w| {\n            w.set_a_inv(config.invert_a);\n            w.set_b_inv(config.invert_b);\n            w.set_ph_correct(config.phase_correct);\n            w.set_en(config.enable);\n        });\n    }\n\n    /// Advances a slice's output phase by one count while it is running\n    /// by inserting a pulse into the clock enable. The counter","sourceCodeStart":237,"sourceCodeEnd":273,"githubUrl":"https://github.com/embassy-rs/embassy/blob/463a07b963419a1bfe61d5d597c44acb810afb8b/embassy-rp/src/pwm.rs#L237-L273","documentation":"PWM channel configuration in embassy-rp validates that the clock divider fits the hardware's 4.12 fixed-point field (12 integer bits + 4 fractional bits, max 0xFFF bits). `set_config`/`configure` panics when `Config::divider` exceeds this maximum, because the value would be truncated in the DIV register.","triggerScenarios":"Setting `Config { divider, .. }` to a value greater than 4095.9375 (0xFFF in U16F4 bits) and calling `Pwm::set_config` or `Pwm::new`.","commonSituations":"Computing a divider as u32/f32 and converting without clamping; aiming for a very low PWM frequency on a high clk_sys and overshooting the divider range; copying a divider value from a datasheet formula that isn't range-checked.","solutions":["Clamp the divider to the representable range before configuring (max FixedU16<U4>::from_bits(0xFFF))","Use `try_set_config` (fallible variant) and handle the error instead of panicking","Lower the PWM top/counter period to achieve the target frequency instead of raising the divider beyond hardware limits","Compute the divider with saturation: `divider.min(FixedU16::<U4>::from_bits(0xFFF))`"],"exampleFix":"// before\nlet config = Config { divider: 8192.into(), top: 100, .. }; // panics\n// after\nlet div = FixedU16::<U4>::from_num(8192.0).min(FixedU16::<U4>::from_bits(0xFFF));\nlet config = Config { divider: div, top: 65535, .. }; // lower freq via larger top","handlingStrategy":"validation","validationCode":"use fixed::types::U4;\nfn divider_valid(d: FixedU16<U4>) -> bool {\n    d <= FixedU16::<U4>::from_bits(0xFFF)\n}","typeGuard":"fn try_divider(d: FixedU16<U4>) -> Option<FixedU16<U4>> {\n    (d <= FixedU16::<U4>::from_bits(0xFFF)).then_some(d)\n}","tryCatchPattern":null,"preventionTips":["Saturate computed dividers before building Config","Achieve low frequencies with larger `top` rather than huge dividers","Prefer try_set_config where available to surface the error gracefully"],"tags":["pwm","embedded","config","rust"],"backgroundTag":"argument-out-of-range","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"}