1use esp_wifi_sys::{
2 c_types::c_char,
3 include::{
4 esp_phy_calibration_data_t,
5 esp_phy_calibration_mode_t,
6 get_phy_version_str,
7 register_chipv7_phy,
8 timeval,
9 },
10};
11use portable_atomic::{AtomicU32, Ordering};
12
13use crate::{
14 binary::include::{esp_event_base_t, esp_timer_get_time},
15 compat::{common::*, timer_compat::*},
16 hal::{self, clock::RadioClockController, peripherals::RADIO_CLK, ram},
17};
18
19#[cfg_attr(esp32c3, path = "common_adapter_esp32c3.rs")]
20#[cfg_attr(esp32c2, path = "common_adapter_esp32c2.rs")]
21#[cfg_attr(esp32c6, path = "common_adapter_esp32c6.rs")]
22#[cfg_attr(esp32h2, path = "common_adapter_esp32h2.rs")]
23#[cfg_attr(esp32, path = "common_adapter_esp32.rs")]
24#[cfg_attr(esp32s3, path = "common_adapter_esp32s3.rs")]
25#[cfg_attr(esp32s2, path = "common_adapter_esp32s2.rs")]
26pub(crate) mod chip_specific;
27
28#[cfg_attr(esp32c3, path = "phy_init_data_esp32c3.rs")]
29#[cfg_attr(esp32c2, path = "phy_init_data_esp32c2.rs")]
30#[cfg_attr(esp32c6, path = "phy_init_data_esp32c6.rs")]
31#[cfg_attr(esp32h2, path = "phy_init_data_esp32h2.rs")]
32#[cfg_attr(esp32, path = "phy_init_data_esp32.rs")]
33#[cfg_attr(esp32s3, path = "phy_init_data_esp32s3.rs")]
34#[cfg_attr(esp32s2, path = "phy_init_data_esp32s2.rs")]
35pub(crate) mod phy_init_data;
36
37#[allow(unused)]
52pub unsafe extern "C" fn semphr_create(max: u32, init: u32) -> *mut crate::binary::c_types::c_void {
53 trace!("semphr_create - max {} init {}", max, init);
54 sem_create(max, init)
55}
56
57#[allow(unused)]
71pub unsafe extern "C" fn semphr_delete(semphr: *mut crate::binary::c_types::c_void) {
72 trace!("semphr_delete {:?}", semphr);
73 sem_delete(semphr);
74}
75
76#[ram]
91pub unsafe extern "C" fn semphr_take(
92 semphr: *mut crate::binary::c_types::c_void,
93 tick: u32,
94) -> i32 {
95 sem_take(semphr, tick)
96}
97
98#[ram]
112pub unsafe extern "C" fn semphr_give(semphr: *mut crate::binary::c_types::c_void) -> i32 {
113 sem_give(semphr)
114}
115
116#[allow(unused)]
120#[ram]
121#[unsafe(no_mangle)]
122pub unsafe extern "C" fn random() -> crate::binary::c_types::c_ulong {
123 trace!("random");
124
125 let mut rng = hal::rng::Rng::new(unsafe { hal::peripherals::RNG::steal() });
127 rng.random()
128}
129
130pub unsafe extern "C" fn read_mac(mac: *mut u8, type_: u32) -> crate::binary::c_types::c_int {
145 trace!("read_mac {:?} {}", mac, type_);
146
147 let base_mac = hal::efuse::Efuse::mac_address();
148
149 for (i, &byte) in base_mac.iter().enumerate() {
150 unsafe {
151 mac.add(i).write_volatile(byte);
152 }
153 }
154
155 unsafe {
156 if type_ == 1 {
158 let tmp = mac.offset(0).read_volatile();
159 for i in 0..64 {
160 mac.offset(0).write_volatile(tmp | 0x02);
161 mac.offset(0)
162 .write_volatile(mac.offset(0).read_volatile() ^ (i << 2));
163
164 if mac.offset(0).read_volatile() != tmp {
165 break;
166 }
167 }
168 }
169
170 if type_ == 2 {
172 let tmp = mac.offset(0).read_volatile();
173 for i in 0..64 {
174 mac.offset(0).write_volatile(tmp | 0x02);
175 mac.offset(0)
176 .write_volatile(mac.offset(0).read_volatile() ^ (i << 2));
177
178 if mac.offset(0).read_volatile() != tmp {
179 break;
180 }
181 }
182
183 mac.offset(5)
184 .write_volatile(mac.offset(5).read_volatile() + 1);
185 }
186 }
187
188 0
189}
190
191#[allow(unused)]
192#[ram]
193pub(crate) unsafe extern "C" fn semphr_take_from_isr(sem: *const (), hptw: *const ()) -> i32 {
194 trace!("sem take from isr");
195 unsafe {
196 (hptw as *mut u32).write_volatile(0);
197 crate::common_adapter::semphr_take(sem as *mut crate::binary::c_types::c_void, 0)
198 }
199}
200
201#[allow(unused)]
202#[ram]
203pub(crate) unsafe extern "C" fn semphr_give_from_isr(sem: *const (), hptw: *const ()) -> i32 {
204 trace!("sem give from isr");
205 unsafe {
206 (hptw as *mut u32).write_volatile(0);
207 crate::common_adapter::semphr_give(sem as *mut crate::binary::c_types::c_void)
208 }
209}
210
211#[unsafe(no_mangle)]
213pub unsafe extern "C" fn puts(s: *const c_char) {
214 unsafe {
215 let cstr = str_from_c(s);
216 info!("{}", cstr);
217 }
218}
219
220#[unsafe(no_mangle)]
222static mut WIFI_EVENT: esp_event_base_t = c"WIFI_EVENT".as_ptr();
223
224#[unsafe(no_mangle)]
226pub unsafe extern "C" fn __assert_func(
227 file: *const c_char,
228 line: u32,
229 func: *const c_char,
230 failed_expr: *const c_char,
231) {
232 unsafe {
233 let file = str_from_c(file);
234 let (func_pre, func) = if func.is_null() {
235 ("", "")
236 } else {
237 (", function: ", str_from_c(func))
238 };
239 let expr = str_from_c(failed_expr);
240
241 panic!(
242 "assertion \"{}\" failed: file \"{}\", line {}{}{}",
243 expr, file, line, func_pre, func
244 );
245 }
246}
247
248#[unsafe(no_mangle)]
249pub unsafe extern "C" fn ets_timer_disarm(timer: *mut crate::binary::c_types::c_void) {
250 compat_timer_disarm(timer.cast());
251}
252
253#[unsafe(no_mangle)]
254pub unsafe extern "C" fn ets_timer_done(timer: *mut crate::binary::c_types::c_void) {
255 compat_timer_done(timer.cast());
256}
257
258#[unsafe(no_mangle)]
259pub unsafe extern "C" fn ets_timer_setfn(
260 ptimer: *mut crate::binary::c_types::c_void,
261 pfunction: *mut crate::binary::c_types::c_void,
262 parg: *mut crate::binary::c_types::c_void,
263) {
264 unsafe {
265 compat_timer_setfn(
266 ptimer.cast(),
267 core::mem::transmute::<
268 *mut crate::binary::c_types::c_void,
269 unsafe extern "C" fn(*mut crate::binary::c_types::c_void),
270 >(pfunction),
271 parg,
272 );
273 }
274}
275
276#[unsafe(no_mangle)]
277pub unsafe extern "C" fn ets_timer_arm(
278 timer: *mut crate::binary::c_types::c_void,
279 tmout: u32,
280 repeat: bool,
281) {
282 compat_timer_arm(timer.cast(), tmout, repeat);
283}
284
285#[unsafe(no_mangle)]
286pub unsafe extern "C" fn ets_timer_arm_us(
287 timer: *mut crate::binary::c_types::c_void,
288 tmout: u32,
289 repeat: bool,
290) {
291 compat_timer_arm_us(timer.cast(), tmout, repeat);
292}
293
294#[unsafe(no_mangle)]
295pub unsafe extern "C" fn gettimeofday(tv: *mut timeval, _tz: *mut ()) -> i32 {
296 if !tv.is_null() {
297 unsafe {
298 let microseconds = esp_timer_get_time();
299 (*tv).tv_sec = (microseconds / 1_000_000) as u64;
300 (*tv).tv_usec = (microseconds % 1_000_000) as u32;
301 }
302 }
303
304 0
305}
306
307#[unsafe(no_mangle)]
308pub unsafe extern "C" fn esp_fill_random(dst: *mut u8, len: u32) {
309 trace!("esp_fill_random");
310 unsafe {
311 let dst = core::slice::from_raw_parts_mut(dst, len as usize);
312
313 let mut rng = esp_hal::rng::Rng::new(esp_hal::peripherals::RNG::steal());
315 for chunk in dst.chunks_mut(4) {
316 let bytes = rng.random().to_le_bytes();
317 chunk.copy_from_slice(&bytes[..chunk.len()]);
318 }
319 }
320}
321
322#[unsafe(no_mangle)]
323pub unsafe extern "C" fn strrchr(_s: *const (), _c: u32) -> *const u8 {
324 todo!("strrchr");
325}
326
327static PHY_CLOCK_ENABLE_REF: AtomicU32 = AtomicU32::new(0);
328
329pub(crate) unsafe fn phy_enable_clock() {
330 let count = PHY_CLOCK_ENABLE_REF.fetch_add(1, Ordering::Acquire);
331 if count == 0 {
332 let radio_clocks = unsafe { RADIO_CLK::steal() };
335 RadioClockController::new(radio_clocks).enable_phy(true);
336 trace!("phy_enable_clock done!");
337 }
338}
339
340#[allow(unused)]
341pub(crate) unsafe fn phy_disable_clock() {
342 let count = PHY_CLOCK_ENABLE_REF.fetch_sub(1, Ordering::Release);
343 if count == 1 {
344 let radio_clocks = unsafe { RADIO_CLK::steal() };
347 RadioClockController::new(radio_clocks).enable_phy(false);
348 trace!("phy_disable_clock done!");
349 }
350}
351
352pub(crate) fn phy_calibrate() {
353 let mut cal_data: [u8; core::mem::size_of::<esp_phy_calibration_data_t>()] =
354 [0u8; core::mem::size_of::<esp_phy_calibration_data_t>()];
355
356 let phy_version = unsafe { get_phy_version_str() };
357 trace!("phy_version {}", unsafe { str_from_c(phy_version) });
358
359 let init_data = &phy_init_data::PHY_INIT_DATA_DEFAULT;
360
361 unsafe {
362 chip_specific::bbpll_en_usb();
363
364 cfg_if::cfg_if! {
365 if #[cfg(phy_full_calibration)] {
366 const CALIBRATION_MODE: esp_phy_calibration_mode_t = esp_wifi_sys::include::esp_phy_calibration_mode_t_PHY_RF_CAL_FULL;
367 } else {
368 const CALIBRATION_MODE: esp_phy_calibration_mode_t = esp_wifi_sys::include::esp_phy_calibration_mode_t_PHY_RF_CAL_PARTIAL;
369 }
370 };
371
372 cfg_if::cfg_if! {
373 if #[cfg(phy_skip_calibration_after_deep_sleep)] {
374 let calibration_mode = if crate::hal::system::reset_reason() == Some(crate::hal::rtc_cntl::SocResetReason::CoreDeepSleep) {
375 esp_wifi_sys::include::esp_phy_calibration_mode_t_PHY_RF_CAL_NONE
376 } else {
377 CALIBRATION_MODE
378 };
379 } else {
380 let calibration_mode = CALIBRATION_MODE;
381 }
382 };
383
384 debug!("Using calibration mode {}", calibration_mode);
385
386 register_chipv7_phy(
387 init_data,
388 &mut cal_data as *mut _ as *mut crate::binary::include::esp_phy_calibration_data_t,
389 calibration_mode,
390 );
391 }
392}