embassy-rs/embassy · error
Error configuring i2c
Error message
Error configuring i2c: {:?} What it means
`I2C::new_inner` in embassy-rp calls `set_config_inner(&config)` and panics if configuration validation fails. `ConfigError` variants cover invalid clock/pin/parameter combinations for the RP2040/RP235x I2C block, so this panic means the supplied `Config` (or derived pin/addresses) cannot be programmed into the hardware.
Solutions
- Print/use the `{:?}` ConfigError in the panic to identify which field is invalid
- Choose a supported I2C frequency (e.g. 100 kHz or 400 kHz) matching your clk_sys frequency
- Use `Config::default(watchdog)` style derived configs so the baudrate is computed from actual clocks
- Switch to the `try_new` / fallible API and handle the error instead of panicking
Example fix
// before
let mut i2c = I2c::new(p.I2C0, scl, sda, Config { frequency: 3_500_000, .. });
// after
let mut i2c = I2c::new(p.I2C0, scl, sda, Config { frequency: 400_000, .. }); Defensive patterns
Strategy: validation
Validate before calling
// Check frequency is achievable before building I2C
let valid = [100_000u32, 400_000u32, 1_000_000u32].contains(&cfg.frequency);
assert!(valid, "unsupported i2c frequency {}", cfg.frequency); Prevention
- Use Config::default derived from the watchdog/clocks so baudrate matches clk_sys
- Keep I2C frequencies at standard 100k/400k values
- Migrate to try_new-style fallible constructors where available
When it happens
Trigger: Calling `I2c::new(...)` or `new_inner` with a `Config` whose values fail `set_config_inner` — e.g. baudrate/baudrate_enum not valid for the current clk_sys, or conflicting configuration for the selected pins.
Common situations: Setting an I2C frequency the hardware divider cannot achieve; running code written for one clock configuration on a board with a different clk_sys frequency; copying a Config from another project without adjusting the baudrate.
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
- All pins must either be <32 or >=16, in
- Requested divider is too large
- Can only take the executor once
- Invalid FilterConfig (TooManyFilters)! A FilterConfig must…
- Invalid FilterConfig (EmptyFilterConfig)! A FilterConfig…
AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10).
Data as JSON: /api/errors/1e9deb4be3a1872b.
Report an issue: GitHub.
Appendix: source
Thrown at embassy-rp/src/i2c.rs:524
impl<'d, M: Mode> I2c<'d, M> {
fn new_inner(info: &'static Info, scl: Peri<'d, AnyPin>, sda: Peri<'d, AnyPin>, config: Config) -> Self {
let reset = (info.reset)();
crate::reset::reset(reset);
crate::reset::unreset_wait(reset);
// Configure SCL & SDA pins
set_up_i2c_pin(&scl, config.scl_pullup);
set_up_i2c_pin(&sda, config.sda_pullup);
let mut me = Self {
info,
phantom: PhantomData,
scl,
sda,
};
if let Err(e) = me.set_config_inner(&config) {
panic!("Error configuring i2c: {:?}", e);
}
me
}
fn set_config_inner(&mut self, config: &Config) -> Result<(), ConfigError> {
if config.frequency.0 > 1_000_000 {
return Err(ConfigError::FrequencyTooHigh);
}
let p = self.info.regs;
p.ic_enable().write(|w| w.set_enable(false));
// Configure baudrate
// There are some subtleties to I2C timing which we are completely
// ignoring here See:View on GitHub (pinned to 463a07b963)