embassy-rs/embassy · error

Invalid transmission power value

Error message

Invalid transmission power value

What it means

set_transmission_power panics when the requested dBm value is not one of the discrete power levels supported by the nRF radio: +8, +4, 0, -4, -8, -12, -16, -20, -30, or -40 dBm. The hardware has a fixed enum of TX power settings, so arbitrary intermediate values cannot be encoded.

Solutions

  1. Snap the requested power to the nearest supported level: [+8, +4, 0, -4, -8, -12, -16, -20, -30, -40] dBm.
  2. Write a helper that maps any i8 to the closest valid level before calling set_transmission_power.
  3. Validate config values at startup against the supported list rather than passing them through.

Example fix

// before
radio.set_transmission_power(power_dbm); // e.g. -3, panics
// after
const LEVELS: [i8; 10] = [8, 4, 0, -4, -8, -12, -16, -20, -30, -40];
let snapped = *LEVELS.iter().min_by_key(|l| (l - power_dbm).abs()).unwrap();
radio.set_transmission_power(snapped);
Defensive patterns

Strategy: validation

Validate before calling

const TX_LEVELS: [i8; 10] = [8, 4, 0, -4, -8, -12, -16, -20, -30, -40];
assert!(TX_LEVELS.contains(&power_dbm), "unsupported TX power {}", power_dbm);
radio.set_transmission_power(power_dbm);

Type guard

fn is_supported_tx_power(dbm: i8) -> bool {
    matches!(dbm, 8 | 4 | 0 | -4 | -8 | -12 | -16 | -20 | -30 | -40)
}

Prevention

When it happens

Trigger: Calling ieee802154::Radio::set_transmission_power with any value other than the supported levels — e.g. set_transmission_power(-3), set_transmission_power(5), or a computed/config value like power = -2*iB.

Common situations: Porting drivers from radios with continuous or different power steps; computing power dynamically from link-quality feedback without snapping to a supported level; config files written in different units (e.g. -3 dBm) instead of the supported steps.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

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

            -1 => TxPower::Neg1dBm,
            #[cfg(feature = "_nrf5340-net")]
            -2 => TxPower::Neg2dBm,
            #[cfg(feature = "_nrf5340-net")]
            -3 => TxPower::Neg3dBm,
            -4 => TxPower::Neg4dBm,
            #[cfg(feature = "_nrf5340-net")]
            -5 => TxPower::Neg5dBm,
            #[cfg(feature = "_nrf5340-net")]
            -6 => TxPower::Neg6dBm,
            #[cfg(feature = "_nrf5340-net")]
            -7 => TxPower::Neg7dBm,
            -8 => TxPower::Neg8dBm,
            -12 => TxPower::Neg12dBm,
            -16 => TxPower::Neg16dBm,
            -20 => TxPower::Neg20dBm,
            -30 => TxPower::Neg30dBm,
            -40 => TxPower::Neg40dBm,
            _ => panic!("Invalid transmission power value"),
        };

        r.txpower().write(|w| w.set_txpower(tx_power));
    }

    /// Waits until the radio state matches the given `state`
    fn wait_for_radio_state(&self, state: RadioState) {
        while self.state() != state {}
    }

    /// Get the current radio state
    fn state(&self) -> RadioState {
        self.r.state().read().state()
    }

    /// Moves the radio from any state to the DISABLED state
    fn disable(&mut self) {
        let r = self.r;

View on GitHub (pinned to 463a07b963)