esp_wifi/common_adapter/
common_adapter_esp32.rs

1use portable_atomic::{AtomicU32, Ordering};
2
3use crate::{
4    binary::include::*,
5    hal::{peripherals::LPWR, ram},
6};
7
8const SOC_PHY_DIG_REGS_MEM_SIZE: usize = 21 * 4;
9
10static mut SOC_PHY_DIG_REGS_MEM: [u8; SOC_PHY_DIG_REGS_MEM_SIZE] = [0u8; SOC_PHY_DIG_REGS_MEM_SIZE];
11static mut G_IS_PHY_CALIBRATED: bool = false;
12static mut G_PHY_DIGITAL_REGS_MEM: *mut u32 = core::ptr::null_mut();
13static mut S_IS_PHY_REG_STORED: bool = false;
14static PHY_ACCESS_REF: AtomicU32 = AtomicU32::new(0);
15
16pub(crate) fn enable_wifi_power_domain() {
17    LPWR::regs()
18        .dig_pwc()
19        .modify(|_, w| w.wifi_force_pd().clear_bit());
20
21    LPWR::regs()
22        .dig_iso()
23        .modify(|_, w| w.wifi_force_iso().clear_bit());
24}
25
26pub(crate) fn phy_mem_init() {
27    unsafe {
28        G_PHY_DIGITAL_REGS_MEM = core::ptr::addr_of_mut!(SOC_PHY_DIG_REGS_MEM).cast();
29    }
30}
31
32pub(crate) unsafe fn bbpll_en_usb() {
33    // nothing for ESP32
34}
35
36pub(crate) unsafe fn phy_enable() {
37    let count = PHY_ACCESS_REF.fetch_add(1, Ordering::SeqCst);
38    if count == 0 {
39        critical_section::with(|_| {
40            // #if CONFIG_IDF_TARGET_ESP32
41            //     // Update time stamp
42            //     s_phy_rf_en_ts = esp_timer_get_time();
43            //     // Update WiFi MAC time before WiFi/BT common clock is enabled
44            //     phy_update_wifi_mac_time(false, s_phy_rf_en_ts);
45            // #endif
46
47            unsafe {
48                super::phy_enable_clock();
49            }
50
51            if unsafe { !G_IS_PHY_CALIBRATED } {
52                super::phy_calibrate();
53                unsafe { G_IS_PHY_CALIBRATED = true };
54            } else {
55                unsafe {
56                    phy_wakeup_init();
57                }
58                phy_digital_regs_load();
59            }
60
61            #[cfg(coex)]
62            unsafe {
63                coex_bt_high_prio();
64            }
65
66            trace!("PHY ENABLE");
67        });
68    }
69}
70
71#[allow(unused)]
72pub(crate) unsafe fn phy_disable() {
73    let count = PHY_ACCESS_REF.fetch_sub(1, Ordering::SeqCst);
74    if count == 1 {
75        critical_section::with(|_| {
76            phy_digital_regs_store();
77            unsafe {
78                // Disable PHY and RF.
79                phy_close_rf();
80
81                // #if CONFIG_IDF_TARGET_ESP32
82                //         // Update WiFi MAC time before disalbe WiFi/BT common peripheral
83                // clock         phy_update_wifi_mac_time(true,
84                // esp_timer_get_time()); #endif
85
86                // Disable WiFi/BT common peripheral clock. Do not disable clock for hardware
87                // RNG
88                super::phy_disable_clock();
89            }
90            trace!("PHY DISABLE");
91        });
92    }
93}
94
95fn phy_digital_regs_load() {
96    unsafe {
97        if S_IS_PHY_REG_STORED && !G_PHY_DIGITAL_REGS_MEM.is_null() {
98            phy_dig_reg_backup(false, G_PHY_DIGITAL_REGS_MEM);
99        }
100    }
101}
102
103fn phy_digital_regs_store() {
104    unsafe {
105        if !G_PHY_DIGITAL_REGS_MEM.is_null() {
106            phy_dig_reg_backup(true, G_PHY_DIGITAL_REGS_MEM);
107            S_IS_PHY_REG_STORED = true;
108        }
109    }
110}
111
112/// **************************************************************************
113/// Name: esp_dport_access_reg_read
114///
115/// Description:
116///   Read regitser value safely in SMP
117///
118/// Input Parameters:
119///   reg - Register address
120///
121/// Returned Value:
122///   Register value
123///
124/// *************************************************************************
125#[ram]
126#[unsafe(no_mangle)]
127unsafe extern "C" fn esp_dport_access_reg_read(reg: u32) -> u32 {
128    unsafe {
129        // trace!("esp_dport_access_reg_read {:x} => {:x}", reg, res);
130        (reg as *mut u32).read_volatile()
131    }
132}
133
134/// **************************************************************************
135/// Name: phy_enter_critical
136///
137/// Description:
138///   Enter critical state
139///
140/// Input Parameters:
141///   None
142///
143/// Returned Value:
144///   CPU PS value
145///
146/// *************************************************************************
147#[ram]
148#[unsafe(no_mangle)]
149unsafe extern "C" fn phy_enter_critical() -> u32 {
150    trace!("phy_enter_critical");
151
152    unsafe { core::mem::transmute(critical_section::acquire()) }
153}
154
155/// **************************************************************************
156/// Name: phy_exit_critical
157///
158/// Description:
159///   Exit from critical state
160///
161/// Input Parameters:
162///   level - CPU PS value
163///
164/// Returned Value:
165///   None
166///
167/// *************************************************************************
168#[ram]
169#[unsafe(no_mangle)]
170unsafe extern "C" fn phy_exit_critical(level: u32) {
171    trace!("phy_exit_critical {}", level);
172
173    unsafe {
174        critical_section::release(core::mem::transmute::<u32, critical_section::RestoreState>(
175            level,
176        ));
177    }
178}
179
180#[ram]
181#[unsafe(no_mangle)]
182unsafe extern "C" fn rtc_get_xtal() -> u32 {
183    use esp_hal::clock::Clock;
184
185    let xtal = crate::hal::rtc_cntl::RtcClock::xtal_freq();
186    xtal.mhz()
187}
188
189#[unsafe(no_mangle)]
190unsafe extern "C" fn misc_nvs_deinit() {
191    trace!("misc_nvs_deinit")
192}
193
194#[unsafe(no_mangle)]
195unsafe extern "C" fn misc_nvs_init() -> i32 {
196    trace!("misc_nvs_init");
197    0
198}
199
200#[unsafe(no_mangle)]
201unsafe extern "C" fn misc_nvs_restore() -> i32 {
202    todo!("misc_nvs_restore")
203}
204
205#[unsafe(no_mangle)]
206static mut g_log_mod: i32 = 0;
207
208#[unsafe(no_mangle)]
209static mut g_log_level: i32 = 0;
210
211#[unsafe(no_mangle)]
212pub static mut g_misc_nvs: u32 = 0;