embassy-rs/embassy · error

Invalid channel for PWM input

Error message

Invalid channel for PWM input

What it means

PWM input capture requires the trigger to come from TI1FP1 or TI2FP2, which only exist for Channel::Ch1 and Channel::Ch2. new_inner panics if the configured channel is Ch3/Ch4, since those channels cannot serve as the PWM-input trigger source.

Solutions

  1. Use Channel::Ch1 or Channel::Ch2 (i.e. a pin mapped to TIMx_CH1 or TIMx_CH2) for the PWM input.
  2. Remap your signal to a pin on CH1/CH2 of the timer, or pick a timer whose CH1/CH2 pins are reachable on your board.

Example fix

// before
let mut pwm_input = PwmInput::new(p.TIM3, p.PB0, Channel::Ch3, config);
// after (PB0 is TIM3_CH3; use a CH1/CH2 pin, e.g. PA6 = TIM3_CH1)
let mut pwm_input = PwmInput::new(p.TIM3, p.PA6, Channel::Ch1, config);
Defensive patterns

Strategy: validation

Validate before calling

fn pwm_input_channel_ok(ch: Channel) -> bool { matches!(ch, Channel::Ch1 | Channel::Ch2) }

Type guard

fn is_ch1_or_ch2(ch: Channel) -> bool { matches!(ch, Channel::Ch1 | Channel::Ch2) }

Prevention

When it happens

Trigger: Constructing a PwmInput with channel Ch3 or Ch4 passed to new / new_inner on a timer where only ch1/ch2 are valid trigger inputs.

Common situations: Wiring the input pin to CH3/CH4 and passing that channel to PwmInput::new; assuming any input-capture channel works for PWM-input mode.

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/a52791027c7ccbe6. Report an issue: GitHub.

Appendix: source

Thrown at embassy-stm32/src/timer/pwm_input.rs:74

        inner.set_counting_mode(CountingMode::EdgeAlignedUp);
        inner.set_tick_freq(freq);
        inner.enable_outputs(); // Required for advanced timers, see GeneralInstance4Channel for details
        inner.generate_update_event();
        inner.start();

        // Configuration steps from ST RM0390 (STM32F446) chapter 17.3.6
        // or ST RM0008 (STM32F103) chapter 15.3.6 Input capture mode
        // or ST RM0440 (STM32G4) chapter 30.4.8 PWM input mode
        inner.set_input_capture_selection(ch1, InputCaptureSelection::Normal);
        inner.set_input_capture_mode(ch1, InputCaptureMode::Rising);

        inner.set_input_capture_selection(ch2, InputCaptureSelection::Alternate);
        inner.set_input_capture_mode(ch2, InputCaptureMode::Falling);

        inner.set_trigger_source(match ch1 {
            Channel::Ch1 => TriggerSource::Ti1fp1,
            Channel::Ch2 => TriggerSource::Ti2fp2,
            _ => panic!("Invalid channel for PWM input"),
        });

        inner.set_slave_mode(SlaveMode::ResetMode);

        // Must call the `enable` function after

        // enable NVIC interrupt
        T::CaptureCompareInterrupt::unpend();
        unsafe { T::CaptureCompareInterrupt::enable() };

        Self {
            channel: ch1,
            inner,
            _wake_guard: T::RCC_INFO.wake_guard(),
        }
    }

    /// Enable the given channel.

View on GitHub (pinned to 463a07b963)