esp_wifi/common_adapter/
common_adapter_esp32c2.rs

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