esp_wifi/common_adapter/
mod.rs

1use esp_wifi_sys::{c_types::c_char, include::timeval};
2use portable_atomic::{AtomicU32, Ordering};
3
4use crate::{
5    binary::include::{esp_event_base_t, esp_timer_get_time},
6    compat::{common::*, timer_compat::*},
7    hal::{self, clock::RadioClockController, peripherals::RADIO_CLK, ram},
8};
9
10#[cfg_attr(esp32c3, path = "common_adapter_esp32c3.rs")]
11#[cfg_attr(esp32c2, path = "common_adapter_esp32c2.rs")]
12#[cfg_attr(esp32c6, path = "common_adapter_esp32c6.rs")]
13#[cfg_attr(esp32h2, path = "common_adapter_esp32h2.rs")]
14#[cfg_attr(esp32, path = "common_adapter_esp32.rs")]
15#[cfg_attr(esp32s3, path = "common_adapter_esp32s3.rs")]
16#[cfg_attr(esp32s2, path = "common_adapter_esp32s2.rs")]
17pub(crate) mod chip_specific;
18
19#[cfg_attr(esp32c3, path = "phy_init_data_esp32c3.rs")]
20#[cfg_attr(esp32c2, path = "phy_init_data_esp32c2.rs")]
21#[cfg_attr(esp32c6, path = "phy_init_data_esp32c6.rs")]
22#[cfg_attr(esp32h2, path = "phy_init_data_esp32h2.rs")]
23#[cfg_attr(esp32, path = "phy_init_data_esp32.rs")]
24#[cfg_attr(esp32s3, path = "phy_init_data_esp32s3.rs")]
25#[cfg_attr(esp32s2, path = "phy_init_data_esp32s2.rs")]
26pub(crate) mod phy_init_data;
27
28/// **************************************************************************
29/// Name: esp_semphr_create
30///
31/// Description:
32///   Create and initialize semaphore
33///
34/// Input Parameters:
35///   max  - No mean
36///   init - semaphore initialization value
37///
38/// Returned Value:
39///   Semaphore data pointer
40///
41/// *************************************************************************
42#[allow(unused)]
43pub unsafe extern "C" fn semphr_create(max: u32, init: u32) -> *mut crate::binary::c_types::c_void {
44    trace!("semphr_create - max {} init {}", max, init);
45    sem_create(max, init)
46}
47
48/// **************************************************************************
49/// Name: esp_semphr_delete
50///
51/// Description:
52///   Delete semaphore
53///
54/// Input Parameters:
55///   semphr - Semaphore data pointer
56///
57/// Returned Value:
58///   None
59///
60/// *************************************************************************
61#[allow(unused)]
62pub unsafe extern "C" fn semphr_delete(semphr: *mut crate::binary::c_types::c_void) {
63    trace!("semphr_delete {:?}", semphr);
64    sem_delete(semphr);
65}
66
67/// **************************************************************************
68/// Name: esp_semphr_take
69///
70/// Description:
71///   Wait semaphore within a certain period of time
72///
73/// Input Parameters:
74///   semphr - Semaphore data pointer
75///   ticks  - Wait system ticks
76///
77/// Returned Value:
78///   True if success or false if fail
79///
80/// *************************************************************************
81#[ram]
82pub unsafe extern "C" fn semphr_take(
83    semphr: *mut crate::binary::c_types::c_void,
84    tick: u32,
85) -> i32 {
86    sem_take(semphr, tick)
87}
88
89/// **************************************************************************
90/// Name: esp_semphr_give
91///
92/// Description:
93///   Post semaphore
94///
95/// Input Parameters:
96///   semphr - Semaphore data pointer
97///
98/// Returned Value:
99///   True if success or false if fail
100///
101/// *************************************************************************
102#[ram]
103pub unsafe extern "C" fn semphr_give(semphr: *mut crate::binary::c_types::c_void) -> i32 {
104    sem_give(semphr)
105}
106
107/// **************************************************************************
108/// Name: esp_random_ulong
109/// *************************************************************************
110#[allow(unused)]
111#[ram]
112#[no_mangle]
113pub unsafe extern "C" fn random() -> crate::binary::c_types::c_ulong {
114    trace!("random");
115
116    // stealing RNG is safe since we own it (passed into `init`)
117    let mut rng = hal::rng::Rng::new(unsafe { hal::peripherals::RNG::steal() });
118    rng.random()
119}
120
121/// **************************************************************************
122/// Name: esp_wifi_read_mac
123///
124/// Description:
125///   Read MAC address from efuse
126///
127/// Input Parameters:
128///   mac  - MAC address buffer pointer
129///   type - MAC address type
130///
131/// Returned Value:
132///   0 if success or -1 if fail
133///
134/// *************************************************************************
135pub unsafe extern "C" fn read_mac(mac: *mut u8, type_: u32) -> crate::binary::c_types::c_int {
136    trace!("read_mac {:?} {}", mac, type_);
137
138    let base_mac = hal::efuse::Efuse::mac_address();
139
140    for (i, &byte) in base_mac.iter().enumerate() {
141        mac.add(i).write_volatile(byte);
142    }
143
144    // ESP_MAC_WIFI_SOFTAP
145    if type_ == 1 {
146        let tmp = mac.offset(0).read_volatile();
147        for i in 0..64 {
148            mac.offset(0).write_volatile(tmp | 0x02);
149            mac.offset(0)
150                .write_volatile(mac.offset(0).read_volatile() ^ (i << 2));
151
152            if mac.offset(0).read_volatile() != tmp {
153                break;
154            }
155        }
156    }
157
158    // ESP_MAC_BT
159    if type_ == 2 {
160        let tmp = mac.offset(0).read_volatile();
161        for i in 0..64 {
162            mac.offset(0).write_volatile(tmp | 0x02);
163            mac.offset(0)
164                .write_volatile(mac.offset(0).read_volatile() ^ (i << 2));
165
166            if mac.offset(0).read_volatile() != tmp {
167                break;
168            }
169        }
170
171        mac.offset(5)
172            .write_volatile(mac.offset(5).read_volatile() + 1);
173    }
174
175    0
176}
177
178#[allow(unused)]
179#[ram]
180pub(crate) unsafe extern "C" fn semphr_take_from_isr(sem: *const (), hptw: *const ()) -> i32 {
181    trace!("sem take from isr");
182    (hptw as *mut u32).write_volatile(0);
183    crate::common_adapter::semphr_take(sem as *mut crate::binary::c_types::c_void, 0)
184}
185
186#[allow(unused)]
187#[ram]
188pub(crate) unsafe extern "C" fn semphr_give_from_isr(sem: *const (), hptw: *const ()) -> i32 {
189    trace!("sem give from isr");
190    (hptw as *mut u32).write_volatile(0);
191    crate::common_adapter::semphr_give(sem as *mut crate::binary::c_types::c_void)
192}
193
194// other functions
195#[no_mangle]
196pub unsafe extern "C" fn puts(s: *const c_char) {
197    let cstr = str_from_c(s);
198    info!("{}", cstr);
199}
200
201// #define ESP_EVENT_DEFINE_BASE(id) esp_event_base_t id = #id
202#[no_mangle]
203static mut WIFI_EVENT: esp_event_base_t = c"WIFI_EVENT".as_ptr();
204
205// stuff needed by wpa-supplicant
206#[no_mangle]
207pub unsafe extern "C" fn __assert_func(
208    file: *const c_char,
209    line: u32,
210    func: *const c_char,
211    failed_expr: *const c_char,
212) {
213    let file = str_from_c(file);
214    let (func_pre, func) = if func.is_null() {
215        ("", "")
216    } else {
217        (", function: ", str_from_c(func))
218    };
219    let expr = str_from_c(failed_expr);
220
221    panic!(
222        "assertion \"{}\" failed: file \"{}\", line {}{}{}",
223        expr, file, line, func_pre, func
224    );
225}
226
227#[no_mangle]
228pub unsafe extern "C" fn ets_timer_disarm(timer: *mut crate::binary::c_types::c_void) {
229    compat_timer_disarm(timer.cast());
230}
231
232#[no_mangle]
233pub unsafe extern "C" fn ets_timer_done(timer: *mut crate::binary::c_types::c_void) {
234    compat_timer_done(timer.cast());
235}
236
237#[no_mangle]
238pub unsafe extern "C" fn ets_timer_setfn(
239    ptimer: *mut crate::binary::c_types::c_void,
240    pfunction: *mut crate::binary::c_types::c_void,
241    parg: *mut crate::binary::c_types::c_void,
242) {
243    compat_timer_setfn(
244        ptimer.cast(),
245        core::mem::transmute::<
246            *mut crate::binary::c_types::c_void,
247            unsafe extern "C" fn(*mut crate::binary::c_types::c_void),
248        >(pfunction),
249        parg,
250    );
251}
252
253#[no_mangle]
254pub unsafe extern "C" fn ets_timer_arm(
255    timer: *mut crate::binary::c_types::c_void,
256    tmout: u32,
257    repeat: bool,
258) {
259    compat_timer_arm(timer.cast(), tmout, repeat);
260}
261
262#[no_mangle]
263pub unsafe extern "C" fn ets_timer_arm_us(
264    timer: *mut crate::binary::c_types::c_void,
265    tmout: u32,
266    repeat: bool,
267) {
268    compat_timer_arm_us(timer.cast(), tmout, repeat);
269}
270
271#[no_mangle]
272pub unsafe extern "C" fn gettimeofday(tv: *mut timeval, _tz: *mut ()) -> i32 {
273    if !tv.is_null() {
274        unsafe {
275            let microseconds = esp_timer_get_time();
276            (*tv).tv_sec = (microseconds / 1_000_000) as u64;
277            (*tv).tv_usec = (microseconds % 1_000_000) as u32;
278        }
279    }
280
281    0
282}
283
284#[no_mangle]
285pub unsafe extern "C" fn esp_fill_random(dst: *mut u8, len: u32) {
286    trace!("esp_fill_random");
287    let dst = core::slice::from_raw_parts_mut(dst, len as usize);
288
289    // stealing RNG is safe since we own it (passed into `init`)
290    let mut rng = esp_hal::rng::Rng::new(unsafe { esp_hal::peripherals::RNG::steal() });
291    for chunk in dst.chunks_mut(4) {
292        let bytes = rng.random().to_le_bytes();
293        chunk.copy_from_slice(&bytes[..chunk.len()]);
294    }
295}
296
297#[no_mangle]
298pub unsafe extern "C" fn strrchr(_s: *const (), _c: u32) -> *const u8 {
299    todo!("strrchr");
300}
301
302// this will result in a duplicate symbol error once `floor` is available
303// ideally we would use weak linkage but that is not stabilized
304// see https://github.com/esp-rs/esp-wifi/pull/191
305#[cfg(feature = "esp32c6")]
306#[no_mangle]
307pub unsafe extern "C" fn floor(v: f64) -> f64 {
308    libm::floor(v)
309}
310
311static PHY_CLOCK_ENABLE_REF: AtomicU32 = AtomicU32::new(0);
312
313pub(crate) unsafe fn phy_enable_clock() {
314    let count = PHY_CLOCK_ENABLE_REF.fetch_add(1, Ordering::Acquire);
315    if count == 0 {
316        // stealing RADIO_CLK is safe since it is passed (as mutable reference or by
317        // value) into `init`
318        let radio_clocks = unsafe { RADIO_CLK::steal() };
319        RadioClockController::new(radio_clocks).enable_phy(true);
320        trace!("phy_enable_clock done!");
321    }
322}
323
324#[allow(unused)]
325pub(crate) unsafe fn phy_disable_clock() {
326    let count = PHY_CLOCK_ENABLE_REF.fetch_sub(1, Ordering::Release);
327    if count == 1 {
328        // stealing RADIO_CLK is safe since it is passed (as mutable reference or by
329        // value) into `init`
330        let radio_clocks = unsafe { RADIO_CLK::steal() };
331        RadioClockController::new(radio_clocks).enable_phy(false);
332        trace!("phy_disable_clock done!");
333    }
334}