embassy-rs/embassy · error

Bad 802.15.4 channel

Error message

Bad 802.15.4 channel

What it means

set_channel panics when the requested 802.15.4 radio channel is outside the IEEE 802.15.4 2.4 GHz band, which spans channels 11-26. The nRF radio can only represent channels 11..=26 as frequency offsets ((channel - 10) * 5 MHz), so any other value is rejected immediately.

Solutions

  1. Pass a channel in 11..=26, e.g. set_channel(11) for 2405 MHz or set_channel(26) for 2480 MHz.
  2. Add a range check or clamp at the call site: assert!(channel >= 11 && channel <= 26) before calling.
  3. If sub-GHz operation is required, this SoC cannot provide it — use a sub-GHz radio chip instead.

Example fix

// before
radio.set_channel(channel); // channel comes from config, may be 15 or 40
// after
assert!((11..=26).contains(&channel), "802.15.4 channel must be 11-26");
radio.set_channel(channel);
Defensive patterns

Strategy: validation

Validate before calling

fn valid_802154_channel(ch: u8) -> bool {
    (11..=26).contains(&ch)
}
assert!(valid_802154_channel(channel));
radio.set_channel(channel);

Type guard

fn is_valid_802154_channel(ch: u8) -> bool { (11..=26).contains(&ch) }

Prevention

When it happens

Trigger: Calling ieee802154::Radio::set_channel with a u8 less than 11 or greater than 26, e.g. set_channel(10), set_channel(27), set_channel(0), or a channel value read from unvalidated network/config data.

Common situations: Porting firmware from sub-GHz 802.15.4 bands (channels 0-10) to the nRF 2.4 GHz radio; parsing channel numbers from network join packets or CLI arguments without validation; using defaults meant for other radios.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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

Appendix: source

Thrown at embassy-nrf/src/radio/ieee802154.rs:119

            r: crate::pac::RADIO,
            state: T::state(),
            needs_enable: false,
            phantom: PhantomData,
        };

        radio.set_sfd(DEFAULT_SFD);
        radio.set_transmission_power(0);
        radio.set_channel(11);
        radio.set_cca(Cca::CarrierSense);

        radio
    }

    /// Changes the radio channel
    pub fn set_channel(&mut self, channel: u8) {
        let r = self.r;
        if channel < 11 || channel > 26 {
            panic!("Bad 802.15.4 channel");
        }
        let frequency_offset = (channel - 10) * 5;
        self.needs_enable = true;
        r.frequency().write(|w| {
            w.set_frequency(frequency_offset);
            w.set_map(vals::Map::Default);
        });
    }

    /// Changes the Clear Channel Assessment method
    pub fn set_cca(&mut self, cca: Cca) {
        let r = self.r;
        self.needs_enable = true;
        match cca {
            Cca::CarrierSense => r.ccactrl().write(|w| w.set_ccamode(vals::Ccamode::CarrierMode)),
            Cca::EnergyDetection { ed_threshold } => {
                // "[ED] is enabled by first configuring the field CCAMODE=EdMode in CCACTRL
                // and writing the CCAEDTHRES field to a chosen value."

View on GitHub (pinned to 463a07b963)