esp_wifi/common_adapter/
common_adapter_esp32c3.rs

1use portable_atomic::{AtomicU32, Ordering};
2
3use super::phy_init_data::PHY_INIT_DATA_DEFAULT;
4use crate::{
5    binary::include::*,
6    compat::common::str_from_c,
7    hal::peripherals::{APB_CTRL, LPWR},
8};
9
10const SOC_PHY_DIG_REGS_MEM_SIZE: usize = 21 * 4;
11
12static mut SOC_PHY_DIG_REGS_MEM: [u8; SOC_PHY_DIG_REGS_MEM_SIZE] = [0u8; SOC_PHY_DIG_REGS_MEM_SIZE];
13static mut G_IS_PHY_CALIBRATED: bool = false;
14static mut G_PHY_DIGITAL_REGS_MEM: *mut u32 = core::ptr::null_mut();
15static mut S_IS_PHY_REG_STORED: bool = false;
16static PHY_ACCESS_REF: AtomicU32 = AtomicU32::new(0);
17
18pub(crate) fn enable_wifi_power_domain() {
19    const SYSTEM_WIFIBB_RST: u32 = 1 << 0;
20    const SYSTEM_FE_RST: u32 = 1 << 1;
21    const SYSTEM_WIFIMAC_RST: u32 = 1 << 2;
22    const SYSTEM_BTBB_RST: u32 = 1 << 3; // Bluetooth Baseband
23    const SYSTEM_BTMAC_RST: u32 = 1 << 4; // deprecated
24    const SYSTEM_RW_BTMAC_RST: u32 = 1 << 9; // Bluetooth MAC
25    const SYSTEM_RW_BTMAC_REG_RST: u32 = 1 << 11; // Bluetooth MAC Regsiters
26    const SYSTEM_BTBB_REG_RST: u32 = 1 << 13; // Bluetooth Baseband Registers
27
28    const MODEM_RESET_FIELD_WHEN_PU: u32 = SYSTEM_WIFIBB_RST
29        | SYSTEM_FE_RST
30        | SYSTEM_WIFIMAC_RST
31        | SYSTEM_BTBB_RST
32        | SYSTEM_BTMAC_RST
33        | SYSTEM_RW_BTMAC_RST
34        | SYSTEM_RW_BTMAC_REG_RST
35        | SYSTEM_BTBB_REG_RST;
36
37    LPWR::regs()
38        .dig_pwc()
39        .modify(|_, w| w.wifi_force_pd().clear_bit());
40
41    APB_CTRL::regs()
42        .wifi_rst_en()
43        .modify(|r, w| unsafe { w.bits(r.bits() | MODEM_RESET_FIELD_WHEN_PU) });
44
45    APB_CTRL::regs()
46        .wifi_rst_en()
47        .modify(|r, w| unsafe { w.bits(r.bits() & !MODEM_RESET_FIELD_WHEN_PU) });
48
49    LPWR::regs()
50        .dig_iso()
51        .modify(|_, w| w.wifi_force_iso().clear_bit());
52}
53
54pub(crate) fn phy_mem_init() {
55    unsafe {
56        G_PHY_DIGITAL_REGS_MEM = core::ptr::addr_of_mut!(SOC_PHY_DIG_REGS_MEM).cast();
57    }
58}
59
60pub(crate) unsafe fn phy_enable() {
61    let count = PHY_ACCESS_REF.fetch_add(1, Ordering::SeqCst);
62    if count == 0 {
63        critical_section::with(|_| {
64            super::phy_enable_clock();
65
66            if !G_IS_PHY_CALIBRATED {
67                let mut cal_data: [u8; core::mem::size_of::<esp_phy_calibration_data_t>()] =
68                    [0u8; core::mem::size_of::<esp_phy_calibration_data_t>()];
69
70                let phy_version = get_phy_version_str();
71                trace!("phy_version {}", str_from_c(phy_version));
72
73                let init_data = &PHY_INIT_DATA_DEFAULT;
74
75                #[cfg(phy_enable_usb)]
76                {
77                    extern "C" {
78                        fn phy_bbpll_en_usb(param: bool);
79                    }
80
81                    phy_bbpll_en_usb(true);
82                }
83
84                register_chipv7_phy(
85                    init_data,
86                    &mut cal_data as *mut _
87                        as *mut crate::binary::include::esp_phy_calibration_data_t,
88                    esp_phy_calibration_mode_t_PHY_RF_CAL_FULL,
89                );
90
91                G_IS_PHY_CALIBRATED = true;
92            } else {
93                phy_wakeup_init();
94                phy_digital_regs_load();
95            }
96
97            #[cfg(feature = "ble")]
98            {
99                extern "C" {
100                    fn coex_pti_v2();
101                }
102                coex_pti_v2();
103            }
104
105            trace!("PHY ENABLE");
106        });
107    }
108}
109
110#[allow(unused)]
111pub(crate) unsafe fn phy_disable() {
112    let count = PHY_ACCESS_REF.fetch_sub(1, Ordering::SeqCst);
113    if count == 1 {
114        critical_section::with(|_| {
115            phy_digital_regs_store();
116            // Disable PHY and RF.
117            phy_close_rf();
118
119            // Disable PHY temperature sensor
120            phy_xpd_tsens();
121
122            // #if CONFIG_IDF_TARGET_ESP32
123            //         // Update WiFi MAC time before disalbe WiFi/BT common peripheral
124            // clock         phy_update_wifi_mac_time(true,
125            // esp_timer_get_time()); #endif
126
127            // Disable WiFi/BT common peripheral clock. Do not disable clock for hardware
128            // RNG
129            super::phy_disable_clock();
130            trace!("PHY DISABLE");
131        });
132    }
133}
134
135fn phy_digital_regs_load() {
136    unsafe {
137        if S_IS_PHY_REG_STORED && !G_PHY_DIGITAL_REGS_MEM.is_null() {
138            phy_dig_reg_backup(false, G_PHY_DIGITAL_REGS_MEM);
139        }
140    }
141}
142
143fn phy_digital_regs_store() {
144    unsafe {
145        if !G_PHY_DIGITAL_REGS_MEM.is_null() {
146            phy_dig_reg_backup(true, G_PHY_DIGITAL_REGS_MEM);
147            S_IS_PHY_REG_STORED = true;
148        }
149    }
150}