embassy-rs/embassy · error

Invalid channel to sample

Error message

Invalid channel to sample

What it means

The L1 ADC sequence configurator writes sample-time fields across four registers (SMPR3..SMPR0) that collectively cover only channels 0..=31. A channel number outside that range has no SMPR slot, so the driver panics rather than silently misconfiguring the ADC.

Solutions

  1. Use only channel values 0..=31 that exist on your L1 device (derive them from embassy's Channel types per pin)
  2. Check the pin-to-channel mapping in the L1 datasheet; fix wrong pin assignments
  3. Ensure you are using embassy-stm32's L1 ADC channel types, not hand-crafted numeric channel IDs

Example fix

// before
adc.sample_sequence(&[Some(unsafe { AnyChannel::new(40) })]); // invalid channel 40
// after
adc.sample_sequence(&[p.PA0]); // valid L1 ADC pin/channel
Defensive patterns

Strategy: validation

Validate before calling

fn valid_channel(ch: u8) -> bool { ch <= 31 }
// call before configure_sequence
assert!(sequence.iter().all(|ch| valid_channel(*ch)), "L1 ADC channels must be 0..=31");

Type guard

fn is_valid_l1_adc_channel(ch: u8) -> bool { ch <= 31 }

Prevention

When it happens

Trigger: Calling `Adc::configure_sequence` (via `sample_sequence`/`read_sequence`) with a sequence containing a channel number > 31, or a channel value that failed conversion to a valid L1 ADC channel.

Common situations: Passing a raw `u8` channel number instead of a typed channel; accidentally using channel enums/indices from another STM32 family (e.g. H7 has higher channel numbers); off-by-one or wrong pin-to-channel mapping.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10). Data as JSON: /api/errors/017b0d97946495ae. Report an issue: GitHub.

Appendix: source

Thrown at embassy-stm32/src/adc/l1.rs:188

        for (i, ((ch, _), sample_time)) in sequence.enumerate() {
            if !injected {
                match i {
                    0..=5 => sqr5.set_sq(i, ch),
                    6..=11 => sqr4.set_sq(i - 6, ch),
                    12..=15 => sqr3.set_sq(i - 12, ch),
                    18..=23 => sqr2.set_sq(i - 18, ch),
                    24..=27 => sqr1.set_sq(i - 24, ch),
                    _ => unreachable!(),
                }
            }

            let sample_time = sample_time.into();
            match ch {
                0..=9 => smpr3.set_smp(ch as _, sample_time),
                10..=19 => smpr2.set_smp(ch as usize - 10, sample_time),
                20..=29 => smpr1.set_smp(ch as usize - 20, sample_time),
                30..=31 => smpr0.set_smp(ch as usize - 30, sample_time),
                _ => panic!("Invalid channel to sample"),
            }
        }

        if !injected {
            self.sqr1().write_value(sqr1);
            self.sqr2().write_value(sqr2);
            self.sqr3().write_value(sqr3);
            self.sqr4().write_value(sqr4);
            self.sqr5().write_value(sqr5);
        }

        self.smpr0().write_value(smpr0);
        self.smpr1().write_value(smpr1);
        self.smpr2().write_value(smpr2);
        self.smpr3().write_value(smpr3);
    }
}

View on GitHub (pinned to 463a07b963)