embassy-rs/embassy · error
Requested divider is too large
Error message
Requested divider is too large
What it means
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.
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))`
Example fix
// before
let config = Config { divider: 8192.into(), top: 100, .. }; // panics
// after
let div = FixedU16::<U4>::from_num(8192.0).min(FixedU16::<U4>::from_bits(0xFFF));
let config = Config { divider: div, top: 65535, .. }; // lower freq via larger top Defensive patterns
Strategy: validation
Validate before calling
use fixed::types::U4;
fn divider_valid(d: FixedU16<U4>) -> bool {
d <= FixedU16::<U4>::from_bits(0xFFF)
} Type guard
fn try_divider(d: FixedU16<U4>) -> Option<FixedU16<U4>> {
(d <= FixedU16::<U4>::from_bits(0xFFF)).then_some(d)
} Prevention
- 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
When it happens
Trigger: Setting `Config { divider, .. }` to a value greater than 4095.9375 (0xFFF in U16F4 bits) and calling `Pwm::set_config` or `Pwm::new`.
Common situations: 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.
Related errors
- The top value cannot be changed after the initialization.
- Error configuring i2c
- All pins must either be <32 or >=16, in
- Can only take the executor once
- Invalid FilterConfig (TooManyFilters)! A FilterConfig must…
AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10).
Data as JSON: /api/errors/5fd180a276b4452d.
Report an issue: GitHub.
Appendix: source
Thrown at embassy-rp/src/pwm.rs:255
) -> Self {
Self::new_inner(
slice.number(),
Some(a.into()),
Some(b.into()),
b_pull,
config,
mode.into(),
)
}
/// Set the PWM config.
pub fn set_config(&mut self, config: &Config) {
Self::configure(pac::PWM.ch(self.slice), config);
}
fn configure(p: pac::pwm::Channel, config: &Config) {
if config.divider > FixedU16::<fixed::types::extra::U4>::from_bits(0xFFF) {
panic!("Requested divider is too large");
}
p.div().write_value(ChDiv(config.divider.to_bits() as u32));
p.cc().write(|w| {
w.set_a(config.compare_a);
w.set_b(config.compare_b);
});
p.top().write(|w| w.set_top(config.top));
p.csr().modify(|w| {
w.set_a_inv(config.invert_a);
w.set_b_inv(config.invert_b);
w.set_ph_correct(config.phase_correct);
w.set_en(config.enable);
});
}
/// Advances a slice's output phase by one count while it is running
/// by inserting a pulse into the clock enable. The counterView on GitHub (pinned to 463a07b963)