use esp_radio::esp_now::{EspNow, PhyMode, RateConfig, WifiPhyRate};
use esp_radio::wifi::SecondaryChannel;
use crate::log_ln;
pub fn install_static_espnow_recv() {
crate::esp_now_pool::install();
}
#[cfg(feature = "esp32c5")]
pub(crate) fn suspend_esp_now_recv() {
unsafe extern "C" {
fn esp_now_unregister_recv_cb() -> i32;
}
unsafe {
let _ = esp_now_unregister_recv_cb();
}
}
#[cfg(feature = "esp32c5")]
pub(crate) fn with_espnow_recv_suspended<F: FnOnce()>(f: F) {
suspend_esp_now_recv();
f();
install_static_espnow_recv();
}
#[cfg(not(feature = "esp32c5"))]
pub(crate) fn with_espnow_recv_suspended<F: FnOnce()>(f: F) {
f();
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct PeerPhy {
pub rate: WifiPhyRate,
pub secondary: Option<SecondaryChannel>,
pub he20: bool,
}
impl PeerPhy {
fn phy_mode(&self) -> PhyMode {
let c = self.rate as u32;
if (16..=35).contains(&c) {
#[cfg(any(feature = "esp32c5", feature = "esp32c6"))]
if self.he20 {
return PhyMode::He20;
}
if self.secondary.is_some() {
PhyMode::Ht40
} else {
PhyMode::Ht20
}
} else if c <= 7 {
PhyMode::_11b
} else {
PhyMode::_11g
}
}
}
pub fn set_peer_espnow_phy(esp_now: &EspNow, peer: &[u8; 6], phy: PeerPhy) {
let phy_mode = phy.phy_mode();
let cfg = RateConfig {
phy_mode,
rate: phy.rate,
ersu: false,
dcm: false,
};
if let Err(e) = esp_now.set_peer_rate(peer, cfg) {
log_ln!(
"ESP-NOW: set_peer_rate failed {:?} phymode={:?} rate={:?}",
e,
phy_mode,
phy.rate
);
}
}
pub fn apply_peer_espnow_phy(esp_now: &EspNow, peer: &[u8; 6], phy: PeerPhy) {
with_espnow_recv_suspended(|| {
set_peer_espnow_phy(esp_now, peer, phy);
});
}