mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-10-02 14:44:42 +00:00

* remove async features * phy-usb config * modem powersaving * Fix examples * make ps a runtime config * fix linting * changelog and migration guide * revert esp-config changes * remove blanklines after doc comments * cfg away ps API
241 lines
6.5 KiB
Rust
241 lines
6.5 KiB
Rust
use portable_atomic::{AtomicU32, Ordering};
|
|
|
|
use super::phy_init_data::PHY_INIT_DATA_DEFAULT;
|
|
use crate::{
|
|
binary::include::*,
|
|
hal::{
|
|
prelude::ram,
|
|
system::{RadioClockController, RadioPeripherals},
|
|
},
|
|
};
|
|
|
|
const SOC_PHY_DIG_REGS_MEM_SIZE: usize = 21 * 4;
|
|
|
|
static mut SOC_PHY_DIG_REGS_MEM: [u8; SOC_PHY_DIG_REGS_MEM_SIZE] = [0u8; SOC_PHY_DIG_REGS_MEM_SIZE];
|
|
static mut G_IS_PHY_CALIBRATED: bool = false;
|
|
static mut G_PHY_DIGITAL_REGS_MEM: *mut u32 = core::ptr::null_mut();
|
|
static mut S_IS_PHY_REG_STORED: bool = false;
|
|
static PHY_ACCESS_REF: AtomicU32 = AtomicU32::new(0);
|
|
static PHY_CLOCK_ENABLE_REF: AtomicU32 = AtomicU32::new(0);
|
|
|
|
pub(crate) fn enable_wifi_power_domain() {
|
|
unsafe {
|
|
let rtc_cntl = &*crate::hal::peripherals::LPWR::ptr();
|
|
|
|
rtc_cntl
|
|
.dig_pwc()
|
|
.modify(|_, w| w.wifi_force_pd().clear_bit());
|
|
|
|
rtc_cntl
|
|
.dig_iso()
|
|
.modify(|_, w| w.wifi_force_iso().clear_bit());
|
|
}
|
|
}
|
|
|
|
pub(crate) fn phy_mem_init() {
|
|
unsafe {
|
|
G_PHY_DIGITAL_REGS_MEM = core::ptr::addr_of_mut!(SOC_PHY_DIG_REGS_MEM).cast();
|
|
}
|
|
}
|
|
|
|
pub(crate) unsafe fn phy_enable() {
|
|
let count = PHY_ACCESS_REF.fetch_add(1, Ordering::SeqCst);
|
|
if count == 0 {
|
|
critical_section::with(|_| {
|
|
// #if CONFIG_IDF_TARGET_ESP32
|
|
// // Update time stamp
|
|
// s_phy_rf_en_ts = esp_timer_get_time();
|
|
// // Update WiFi MAC time before WiFi/BT common clock is enabled
|
|
// phy_update_wifi_mac_time(false, s_phy_rf_en_ts);
|
|
// #endif
|
|
|
|
phy_enable_clock();
|
|
|
|
if !G_IS_PHY_CALIBRATED {
|
|
let mut cal_data: [u8; core::mem::size_of::<esp_phy_calibration_data_t>()] =
|
|
[0u8; core::mem::size_of::<esp_phy_calibration_data_t>()];
|
|
|
|
let init_data = &PHY_INIT_DATA_DEFAULT;
|
|
|
|
register_chipv7_phy(
|
|
init_data,
|
|
&mut cal_data as *mut _
|
|
as *mut crate::binary::include::esp_phy_calibration_data_t,
|
|
esp_phy_calibration_mode_t_PHY_RF_CAL_FULL,
|
|
);
|
|
|
|
G_IS_PHY_CALIBRATED = true;
|
|
} else {
|
|
phy_wakeup_init();
|
|
phy_digital_regs_load();
|
|
}
|
|
|
|
#[cfg(coex)]
|
|
coex_bt_high_prio();
|
|
|
|
trace!("PHY ENABLE");
|
|
});
|
|
}
|
|
}
|
|
|
|
#[allow(unused)]
|
|
pub(crate) unsafe fn phy_disable() {
|
|
let count = PHY_ACCESS_REF.fetch_sub(1, Ordering::SeqCst);
|
|
if count == 1 {
|
|
critical_section::with(|_| {
|
|
phy_digital_regs_store();
|
|
// Disable PHY and RF.
|
|
phy_close_rf();
|
|
|
|
// #if CONFIG_IDF_TARGET_ESP32
|
|
// // Update WiFi MAC time before disalbe WiFi/BT common peripheral
|
|
// clock phy_update_wifi_mac_time(true,
|
|
// esp_timer_get_time()); #endif
|
|
|
|
// Disable WiFi/BT common peripheral clock. Do not disable clock for hardware
|
|
// RNG
|
|
phy_disable_clock();
|
|
trace!("PHY DISABLE");
|
|
});
|
|
}
|
|
}
|
|
|
|
fn phy_digital_regs_load() {
|
|
unsafe {
|
|
if S_IS_PHY_REG_STORED && !G_PHY_DIGITAL_REGS_MEM.is_null() {
|
|
phy_dig_reg_backup(false, G_PHY_DIGITAL_REGS_MEM);
|
|
}
|
|
}
|
|
}
|
|
|
|
fn phy_digital_regs_store() {
|
|
unsafe {
|
|
if !G_PHY_DIGITAL_REGS_MEM.is_null() {
|
|
phy_dig_reg_backup(true, G_PHY_DIGITAL_REGS_MEM);
|
|
S_IS_PHY_REG_STORED = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
pub(crate) unsafe fn phy_enable_clock() {
|
|
trace!("phy_enable_clock");
|
|
|
|
let count = PHY_CLOCK_ENABLE_REF.fetch_add(1, Ordering::SeqCst);
|
|
if count == 0 {
|
|
// stealing RADIO_CLK is safe since it is passed (as mutable reference or by
|
|
// value) into `init`
|
|
let mut radio_clocks = unsafe { esp_hal::peripherals::RADIO_CLK::steal() };
|
|
radio_clocks.enable(RadioPeripherals::Phy);
|
|
}
|
|
}
|
|
|
|
#[allow(unused)]
|
|
pub(crate) unsafe fn phy_disable_clock() {
|
|
trace!("phy_disable_clock");
|
|
|
|
let count = PHY_CLOCK_ENABLE_REF.fetch_sub(1, Ordering::SeqCst);
|
|
if count == 1 {
|
|
// stealing RADIO_CLK is safe since it is passed (as mutable reference or by
|
|
// value) into `init`
|
|
let mut radio_clocks = unsafe { esp_hal::peripherals::RADIO_CLK::steal() };
|
|
radio_clocks.disable(RadioPeripherals::Phy);
|
|
}
|
|
}
|
|
|
|
/// **************************************************************************
|
|
/// Name: esp_dport_access_reg_read
|
|
///
|
|
/// Description:
|
|
/// Read regitser value safely in SMP
|
|
///
|
|
/// Input Parameters:
|
|
/// reg - Register address
|
|
///
|
|
/// Returned Value:
|
|
/// Register value
|
|
///
|
|
/// *************************************************************************
|
|
#[ram]
|
|
#[no_mangle]
|
|
unsafe extern "C" fn esp_dport_access_reg_read(reg: u32) -> u32 {
|
|
// trace!("esp_dport_access_reg_read {:x} => {:x}", reg, res);
|
|
(reg as *mut u32).read_volatile()
|
|
}
|
|
|
|
/// **************************************************************************
|
|
/// Name: phy_enter_critical
|
|
///
|
|
/// Description:
|
|
/// Enter critical state
|
|
///
|
|
/// Input Parameters:
|
|
/// None
|
|
///
|
|
/// Returned Value:
|
|
/// CPU PS value
|
|
///
|
|
/// *************************************************************************
|
|
#[ram]
|
|
#[no_mangle]
|
|
unsafe extern "C" fn phy_enter_critical() -> u32 {
|
|
trace!("phy_enter_critical");
|
|
|
|
core::mem::transmute(critical_section::acquire())
|
|
}
|
|
|
|
/// **************************************************************************
|
|
/// Name: phy_exit_critical
|
|
///
|
|
/// Description:
|
|
/// Exit from critical state
|
|
///
|
|
/// Input Parameters:
|
|
/// level - CPU PS value
|
|
///
|
|
/// Returned Value:
|
|
/// None
|
|
///
|
|
/// *************************************************************************
|
|
#[ram]
|
|
#[no_mangle]
|
|
unsafe extern "C" fn phy_exit_critical(level: u32) {
|
|
trace!("phy_exit_critical {}", level);
|
|
|
|
critical_section::release(core::mem::transmute::<u32, critical_section::RestoreState>(
|
|
level,
|
|
));
|
|
}
|
|
|
|
#[ram]
|
|
#[no_mangle]
|
|
unsafe extern "C" fn rtc_get_xtal() -> u32 {
|
|
use crate::hal::clock::Clock;
|
|
let xtal = crate::hal::rtc_cntl::RtcClock::get_xtal_freq();
|
|
xtal.mhz()
|
|
}
|
|
|
|
#[no_mangle]
|
|
unsafe extern "C" fn misc_nvs_deinit() {
|
|
trace!("misc_nvs_deinit")
|
|
}
|
|
|
|
#[no_mangle]
|
|
unsafe extern "C" fn misc_nvs_init() -> i32 {
|
|
trace!("misc_nvs_init");
|
|
0
|
|
}
|
|
|
|
#[no_mangle]
|
|
unsafe extern "C" fn misc_nvs_restore() -> i32 {
|
|
todo!("misc_nvs_restore")
|
|
}
|
|
|
|
#[no_mangle]
|
|
static mut g_log_mod: i32 = 0;
|
|
|
|
#[no_mangle]
|
|
static mut g_log_level: i32 = 0;
|
|
|
|
#[no_mangle]
|
|
pub static mut g_misc_nvs: u32 = 0;
|