esp_wifi/common_adapter/
common_adapter_esp32c6.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, SOC_PMU_SUPPORTED is set which makes
16    // `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                #[cfg(phy_enable_usb)]
41                {
42                    extern "C" {
43                        fn phy_bbpll_en_usb(param: bool);
44                    }
45
46                    phy_bbpll_en_usb(true);
47                }
48                register_chipv7_phy(
49                    init_data,
50                    &mut cal_data as *mut _
51                        as *mut crate::binary::include::esp_phy_calibration_data_t,
52                    esp_phy_calibration_mode_t_PHY_RF_CAL_FULL,
53                );
54
55                G_IS_PHY_CALIBRATED = true;
56            } else {
57                phy_wakeup_init();
58                phy_digital_regs_load();
59            }
60
61            #[cfg(feature = "ble")]
62            {
63                extern "C" {
64                    fn coex_pti_v2();
65                }
66                coex_pti_v2();
67            }
68
69            trace!("PHY ENABLE");
70        });
71    }
72}
73
74#[allow(unused)]
75pub(crate) unsafe fn phy_disable() {
76    let count = PHY_ACCESS_REF.fetch_sub(1, Ordering::SeqCst);
77    if count == 1 {
78        critical_section::with(|_| {
79            phy_digital_regs_store();
80            // Disable PHY and RF.
81            phy_close_rf();
82
83            // Disable PHY temperature sensor
84            phy_xpd_tsens();
85
86            // #if CONFIG_IDF_TARGET_ESP32
87            //         // Update WiFi MAC time before disable WiFi/BT common peripheral
88            // clock         phy_update_wifi_mac_time(true,
89            // esp_timer_get_time()); #endif
90
91            // Disable WiFi/BT common peripheral clock. Do not disable clock for hardware
92            // RNG
93            super::phy_disable_clock();
94            trace!("PHY DISABLE");
95        });
96    }
97}
98
99fn phy_digital_regs_load() {
100    unsafe {
101        if S_IS_PHY_REG_STORED && !G_PHY_DIGITAL_REGS_MEM.is_null() {
102            phy_dig_reg_backup(false, G_PHY_DIGITAL_REGS_MEM);
103        }
104    }
105}
106
107fn phy_digital_regs_store() {
108    unsafe {
109        if !G_PHY_DIGITAL_REGS_MEM.is_null() {
110            phy_dig_reg_backup(true, G_PHY_DIGITAL_REGS_MEM);
111            S_IS_PHY_REG_STORED = true;
112        }
113    }
114}