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; const SYSTEM_BTMAC_RST: u32 = 1 << 4; const SYSTEM_RW_BTMAC_RST: u32 = 1 << 9; const SYSTEM_RW_BTMAC_REG_RST: u32 = 1 << 11; const SYSTEM_BTBB_REG_RST: u32 = 1 << 13; 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 phy_close_rf();
118
119 phy_xpd_tsens();
121
122 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}