esp_wifi/common_adapter/
common_adapter_esp32h2.rs

1// use atomic_polyfill::AtomicU32;
2use portable_atomic::{AtomicU32, Ordering};
3
4use super::phy_init_data::PHY_INIT_DATA_DEFAULT;
5use crate::{binary::include::*, compat::common::str_from_c};
6
7const SOC_PHY_DIG_REGS_MEM_SIZE: usize = 21 * 4;
8
9static mut SOC_PHY_DIG_REGS_MEM: [u8; SOC_PHY_DIG_REGS_MEM_SIZE] = [0u8; SOC_PHY_DIG_REGS_MEM_SIZE];
10static mut G_IS_PHY_CALIBRATED: bool = false;
11static mut G_PHY_DIGITAL_REGS_MEM: *mut u32 = core::ptr::null_mut();
12static mut S_IS_PHY_REG_STORED: bool = false;
13static PHY_ACCESS_REF: AtomicU32 = AtomicU32::new(0);
14
15pub(crate) fn enable_wifi_power_domain() {
16    // In esp-idf, SOC_PMU_SUPPORTED is set which makes
17    // `esp_wifi_bt_power_domain_on` a no-op.
18}
19
20pub(crate) fn phy_mem_init() {
21    unsafe {
22        G_PHY_DIGITAL_REGS_MEM = core::ptr::addr_of_mut!(SOC_PHY_DIG_REGS_MEM).cast();
23    }
24}
25
26pub(crate) unsafe fn phy_enable() {
27    let count = PHY_ACCESS_REF.fetch_add(1, Ordering::SeqCst);
28    if count == 0 {
29        critical_section::with(|_| {
30            super::phy_enable_clock();
31
32            if !G_IS_PHY_CALIBRATED {
33                let mut cal_data: [u8; core::mem::size_of::<esp_phy_calibration_data_t>()] =
34                    [0u8; core::mem::size_of::<esp_phy_calibration_data_t>()];
35
36                let phy_version = get_phy_version_str();
37                trace!("phy_version {}", str_from_c(phy_version));
38
39                let init_data = &PHY_INIT_DATA_DEFAULT;
40
41                // this would cause linker errors when the feature is activated - see https://github.com/esp-rs/esp-wifi/issues/457
42
43                // #[cfg(phy_enable_usb)]
44                // {
45                //     extern "C" {
46                //         pub fn phy_bbpll_en_usb(param: bool);
47                //     }
48
49                //     phy_bbpll_en_usb(true);
50                // }
51                register_chipv7_phy(
52                    init_data,
53                    &mut cal_data as *mut _
54                        as *mut crate::binary::include::esp_phy_calibration_data_t,
55                    esp_phy_calibration_mode_t_PHY_RF_CAL_FULL,
56                );
57
58                G_IS_PHY_CALIBRATED = true;
59            } else {
60                phy_wakeup_init();
61                phy_digital_regs_load();
62            }
63
64            #[cfg(feature = "ble")]
65            {
66                extern "C" {
67                    fn coex_pti_v2();
68                }
69                coex_pti_v2();
70            }
71
72            trace!("PHY ENABLE");
73        });
74    }
75}
76
77#[allow(unused)]
78pub(crate) unsafe fn phy_disable() {
79    let count = PHY_ACCESS_REF.fetch_sub(1, Ordering::SeqCst);
80    if count == 1 {
81        critical_section::with(|_| {
82            phy_digital_regs_store();
83            // Disable PHY and RF.
84            phy_close_rf();
85
86            // Disable PHY temperature sensor
87            phy_xpd_tsens();
88
89            // #if CONFIG_IDF_TARGET_ESP32
90            //         // Update WiFi MAC time before disalbe WiFi/BT common peripheral
91            // clock         phy_update_wifi_mac_time(true,
92            // esp_timer_get_time()); #endif
93
94            // Disable WiFi/BT common peripheral clock. Do not disable clock for hardware
95            // RNG
96            super::phy_disable_clock();
97            trace!("PHY DISABLE");
98        });
99    }
100}
101
102fn phy_digital_regs_load() {
103    unsafe {
104        if S_IS_PHY_REG_STORED && !G_PHY_DIGITAL_REGS_MEM.is_null() {
105            phy_dig_reg_backup(false, G_PHY_DIGITAL_REGS_MEM);
106        }
107    }
108}
109
110fn phy_digital_regs_store() {
111    unsafe {
112        if !G_PHY_DIGITAL_REGS_MEM.is_null() {
113            phy_dig_reg_backup(true, G_PHY_DIGITAL_REGS_MEM);
114            S_IS_PHY_REG_STORED = true;
115        }
116    }
117}