From 054c5b0b7864e4e9ebe22a74379ae063f74ea60b Mon Sep 17 00:00:00 2001 From: Juraj Sadel Date: Wed, 6 Dec 2023 12:55:12 +0100 Subject: [PATCH] H2: Add BLE support (#352) * H2: Add BLE support * fix ci * fix ci 2 * Add H2 into test scripts * update to latest changes * revert smoltcp change * Update smoketest.bat Co-authored-by: Scott Mabin --------- Co-authored-by: Scott Mabin --- esp-wifi/.cargo/config.toml | 6 +- esp-wifi/Cargo.toml | 6 + esp-wifi/automated-tests/test_ble.rs | 2 +- esp-wifi/build.rs | 19 ++- esp-wifi/examples/ble.rs | 7 +- esp-wifi/examples/embassy_ble.rs | 7 +- esp-wifi/src/ble/mod.rs | 4 +- esp-wifi/src/ble/npl.rs | 1 + esp-wifi/src/ble/os_adapter_esp32h2.rs | 128 +++++++++++++++ .../common_adapter/common_adapter_esp32h2.rs | 137 ++++++++++++++++ esp-wifi/src/common_adapter/mod.rs | 2 + .../common_adapter/phy_init_data_esp32h2.rs | 146 ++++++++++++++++++ esp-wifi/src/lib.rs | 9 +- esp-wifi/src/timer/mod.rs | 3 +- esp-wifi/src/timer/riscv.rs | 4 +- esp-wifi/src/timer/timer_esp32h2.rs | 62 ++++++++ esp-wifi/src/wifi/mod.rs | 2 +- esp-wifi/src/wifi/os_adapter.rs | 3 +- esp-wifi/src/wifi/os_adapter_esp32h2.rs | 95 ++++++++++++ 19 files changed, 627 insertions(+), 16 deletions(-) create mode 100644 esp-wifi/src/ble/os_adapter_esp32h2.rs create mode 100644 esp-wifi/src/common_adapter/common_adapter_esp32h2.rs create mode 100644 esp-wifi/src/common_adapter/phy_init_data_esp32h2.rs create mode 100644 esp-wifi/src/timer/timer_esp32h2.rs create mode 100644 esp-wifi/src/wifi/os_adapter_esp32h2.rs diff --git a/esp-wifi/.cargo/config.toml b/esp-wifi/.cargo/config.toml index 83c7032dc10..872463e86f8 100644 --- a/esp-wifi/.cargo/config.toml +++ b/esp-wifi/.cargo/config.toml @@ -1,5 +1,5 @@ # Alias' for quickly building for different chips or running examples -# By default we enable +# By default we enable # - `default` HAL features to set up basic chip specific settings # - `embassy-time-timg0` as the examples assume we are using this time driver # - `embassy-executor-thread` on Xtensa chips to take advantage of the Xtensa specific executor we have in esp-hal @@ -10,6 +10,7 @@ esp32s3 = "run --features esp32s3 --target xtensa-esp32s3-none-elf --featur esp32c2 = "run --features esp32c2 --target riscv32imc-unknown-none-elf --features esp32c2-hal/default,esp32c2-hal/embassy-time-timg0,esp32c2-hal/embassy-executor-thread" esp32c3 = "run --features esp32c3 --target riscv32imc-unknown-none-elf --features esp32c3-hal/default,esp32c3-hal/embassy-time-timg0,esp32c3-hal/embassy-executor-thread" esp32c6 = "run --features esp32c6 --target riscv32imac-unknown-none-elf --features esp32c6-hal/default,esp32c6-hal/embassy-time-timg0,esp32c6-hal/embassy-executor-thread" +esp32h2 = "run --features esp32h2 --target riscv32imac-unknown-none-elf --features esp32h2-hal/default,esp32h2-hal/embassy-time-timg0,esp32h2-hal/embassy-executor-thread" besp32 = "build --features esp32 --target xtensa-esp32-none-elf --features esp32-hal/default,esp32-hal/embassy-time-timg0,esp32-hal/embassy-executor-thread" besp32s2 = "build --features esp32s2 --target xtensa-esp32s2-none-elf --features esp32s2-hal/default,esp32s2-hal/embassy-time-timg0,esp32s2-hal/embassy-executor-thread" @@ -17,6 +18,7 @@ besp32s3 = "build --features esp32s3 --target xtensa-esp32s3-none-elf --fea besp32c2 = "build --features esp32c2 --target riscv32imc-unknown-none-elf --features esp32c2-hal/default,esp32c2-hal/embassy-time-timg0,esp32c2-hal/embassy-executor-thread" besp32c3 = "build --features esp32c3 --target riscv32imc-unknown-none-elf --features esp32c3-hal/default,esp32c3-hal/embassy-time-timg0,esp32c3-hal/embassy-executor-thread" besp32c6 = "build --features esp32c6 --target riscv32imac-unknown-none-elf --features esp32c6-hal/default,esp32c6-hal/embassy-time-timg0,esp32c6-hal/embassy-executor-thread" +besp32h2 = "build --features esp32h2 --target riscv32imac-unknown-none-elf --features esp32h2-hal/default,esp32h2-hal/embassy-time-timg0,esp32h2-hal/embassy-executor-thread" [target.riscv32imc-unknown-none-elf] runner = "espflash flash --monitor" @@ -57,4 +59,4 @@ rustflags = [ ] [unstable] -build-std = [ "core" ] +build-std = [ "core" ] \ No newline at end of file diff --git a/esp-wifi/Cargo.toml b/esp-wifi/Cargo.toml index 58125a19ac3..a03485e7149 100644 --- a/esp-wifi/Cargo.toml +++ b/esp-wifi/Cargo.toml @@ -26,6 +26,7 @@ defmt = { workspace = true, optional = true } esp32c3-hal = { workspace = true, optional = true } esp32c2-hal = { workspace = true, optional = true } esp32c6-hal = { workspace = true, optional = true } +esp32h2-hal = { workspace = true, optional = true } esp32-hal = { workspace = true, optional = true } esp32s3-hal = { workspace = true, optional = true } esp32s2-hal = { workspace = true, optional = true } @@ -75,6 +76,7 @@ default = [ "log", "ipv4", "tcp", "udp", "icmp", "igmp", "dns", "dhcpv4" ] esp32c2 = [ "esp32c2-hal", "esp-wifi-sys/esp32c2", "esp-println/esp32c2", "esp-backtrace/esp32c2" ] esp32c3 = [ "esp32c3-hal", "esp-wifi-sys/esp32c3", "esp-println/esp32c3", "esp-backtrace/esp32c3" ] esp32c6 = [ "esp32c6-hal", "esp-wifi-sys/esp32c6", "esp-println/esp32c6", "esp-backtrace/esp32c6" ] +esp32h2 = [ "esp32h2-hal", "esp-wifi-sys/esp32h2", "esp-println/esp32h2", "esp-backtrace/esp32h2" ] esp32 = [ "esp32-hal", "esp-wifi-sys/esp32", "esp-println/esp32", "esp-backtrace/esp32" ] esp32s2 = [ "esp32s2-hal", "esp-wifi-sys/esp32s2", "esp-println/esp32s2", "esp-backtrace/esp32s2" ] esp32s3 = [ "esp32s3-hal", "esp-wifi-sys/esp32s3", "esp-println/esp32s3", "esp-backtrace/esp32s3" ] @@ -87,12 +89,14 @@ async = [ "esp32c3-hal?/embassy", "esp32c2-hal?/embassy", "esp32c6-hal?/embassy", + "esp32h2-hal?/embassy", "esp32-hal?/embassy", "esp32s2-hal?/embassy", "esp32s3-hal?/embassy", "esp32c3-hal?/async", "esp32c2-hal?/async", "esp32c6-hal?/async", + "esp32h2-hal?/async", "esp32-hal?/async", "esp32s2-hal?/async", "esp32s3-hal?/async", @@ -127,6 +131,7 @@ defmt = [ "esp32c3-hal?/defmt", "esp32c2-hal?/defmt", "esp32c6-hal?/defmt", + "esp32h2-hal?/defmt", "esp32-hal?/defmt", "esp32s2-hal?/defmt", "esp32s3-hal?/defmt", @@ -136,6 +141,7 @@ log = [ "esp32c3-hal?/log", "esp32c2-hal?/log", "esp32c6-hal?/log", + "esp32h2-hal?/log", "esp32-hal?/log", "esp32s2-hal?/log", "esp32s3-hal?/log", diff --git a/esp-wifi/automated-tests/test_ble.rs b/esp-wifi/automated-tests/test_ble.rs index f5aaf5b7051..6b50d457568 100644 --- a/esp-wifi/automated-tests/test_ble.rs +++ b/esp-wifi/automated-tests/test_ble.rs @@ -14,7 +14,7 @@ use esp_backtrace as _; use esp_println::println; use esp_wifi::{ble::controller::BleConnector, initialize, EspWifiInitFor}; use examples_util::hal; -use hal::{clock::ClockControl, peripherals::*, prelude::*, Rng, IO}; +use hal::{clock::ClockControl, peripherals::*, prelude::*, Rng}; #[path = "../../examples-util/util.rs"] mod examples_util; diff --git a/esp-wifi/build.rs b/esp-wifi/build.rs index c154722f1a0..1b2fca38a9b 100644 --- a/esp-wifi/build.rs +++ b/esp-wifi/build.rs @@ -3,6 +3,7 @@ feature = "esp32c2", feature = "esp32c3", feature = "esp32c6", + feature = "esp32h2", feature = "esp32s2", feature = "esp32s3", ))] @@ -17,12 +18,22 @@ fn main() -> Result<(), String> { "# ); } + #[cfg(all(feature = "wifi", feature = "esp32h2"))] + { + panic!( + r#" + + WiFi is not supported on this target. + + "# + ); + } #[cfg(all(feature = "coex", any(feature = "esp32s2")))] { panic!( r#" - COEX is not yet supported on this target. + COEX is not yet supported on this target. See https://github.com/esp-rs/esp-wifi/issues/92. @@ -33,7 +44,7 @@ fn main() -> Result<(), String> { Ok(level) => { if level != "2" && level != "3" { let message = format!( - "esp-wifi should be built with optimization level 2 or 3 - yours is {level}. + "esp-wifi should be built with optimization level 2 or 3 - yours is {level}. See https://github.com/esp-rs/esp-wifi", ); print_warning(message); @@ -54,6 +65,9 @@ fn main() -> Result<(), String> { #[cfg(feature = "esp32c6")] println!("cargo:rustc-cfg=esp32c6"); + #[cfg(feature = "esp32h2")] + println!("cargo:rustc-cfg=esp32h2"); + #[cfg(feature = "esp32s2")] println!("cargo:rustc-cfg=esp32s2"); @@ -124,6 +138,7 @@ fn try_read_xtensa_rustc_version(version: &str) -> Option { feature = "esp32c2", feature = "esp32c3", feature = "esp32c6", + feature = "esp32h2", feature = "esp32s2", feature = "esp32s3", )))] diff --git a/esp-wifi/examples/ble.rs b/esp-wifi/examples/ble.rs index 98be8d44d5c..1fe30d19598 100644 --- a/esp-wifi/examples/ble.rs +++ b/esp-wifi/examples/ble.rs @@ -42,7 +42,12 @@ fn main() -> ! { let io = IO::new(peripherals.GPIO, peripherals.IO_MUX); #[cfg(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3"))] let button = io.pins.gpio0.into_pull_down_input(); - #[cfg(any(feature = "esp32c2", feature = "esp32c3", feature = "esp32c6"))] + #[cfg(any( + feature = "esp32c2", + feature = "esp32c3", + feature = "esp32c6", + feature = "esp32h2" + ))] let button = io.pins.gpio9.into_pull_down_input(); let mut debounce_cnt = 500; diff --git a/esp-wifi/examples/embassy_ble.rs b/esp-wifi/examples/embassy_ble.rs index 10a640ecda5..963625f306d 100644 --- a/esp-wifi/examples/embassy_ble.rs +++ b/esp-wifi/examples/embassy_ble.rs @@ -50,7 +50,12 @@ async fn main(_spawner: Spawner) -> ! { let io = IO::new(peripherals.GPIO, peripherals.IO_MUX); #[cfg(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3"))] let button = io.pins.gpio0.into_pull_down_input(); - #[cfg(any(feature = "esp32c2", feature = "esp32c3", feature = "esp32c6"))] + #[cfg(any( + feature = "esp32c2", + feature = "esp32c3", + feature = "esp32c6", + feature = "esp32h2" + ))] let button = io.pins.gpio9.into_pull_down_input(); // Async requires the GPIO interrupt to wake futures diff --git a/esp-wifi/src/ble/mod.rs b/esp-wifi/src/ble/mod.rs index aa848911579..c676064a121 100644 --- a/esp-wifi/src/ble/mod.rs +++ b/esp-wifi/src/ble/mod.rs @@ -3,7 +3,7 @@ #[cfg(any(esp32, esp32c3, esp32s3))] pub(crate) mod btdm; -#[cfg(any(esp32c2, esp32c6))] +#[cfg(any(esp32c2, esp32c6, esp32h2))] pub(crate) mod npl; use core::mem::MaybeUninit; @@ -11,7 +11,7 @@ use core::mem::MaybeUninit; #[cfg(any(esp32, esp32c3, esp32s3))] use self::btdm as ble; -#[cfg(any(esp32c2, esp32c6))] +#[cfg(any(esp32c2, esp32c6, esp32h2))] use self::npl as ble; pub(crate) use ble::ble_init; diff --git a/esp-wifi/src/ble/npl.rs b/esp-wifi/src/ble/npl.rs index 8bf088e1775..41503408ab7 100644 --- a/esp-wifi/src/ble/npl.rs +++ b/esp-wifi/src/ble/npl.rs @@ -16,6 +16,7 @@ use crate::timer::yield_task; #[cfg_attr(esp32c2, path = "os_adapter_esp32c2.rs")] #[cfg_attr(esp32c6, path = "os_adapter_esp32c6.rs")] +#[cfg_attr(esp32h2, path = "os_adapter_esp32h2.rs")] pub(crate) mod ble_os_adapter_chip_specific; const TIME_FOREVER: u32 = u32::MAX; diff --git a/esp-wifi/src/ble/os_adapter_esp32h2.rs b/esp-wifi/src/ble/os_adapter_esp32h2.rs new file mode 100644 index 00000000000..af262ac19a4 --- /dev/null +++ b/esp-wifi/src/ble/os_adapter_esp32h2.rs @@ -0,0 +1,128 @@ +use crate::binary::include::esp_bt_controller_config_t; +use crate::common_adapter::RADIO_CLOCKS; +use crate::hal::system::RadioClockController; +use crate::hal::system::RadioPeripherals; + +pub(crate) static mut ISR_INTERRUPT_15: ( + *mut crate::binary::c_types::c_void, + *mut crate::binary::c_types::c_void, +) = (core::ptr::null_mut(), core::ptr::null_mut()); + +pub(crate) static mut ISR_INTERRUPT_3: ( + *mut crate::binary::c_types::c_void, + *mut crate::binary::c_types::c_void, +) = (core::ptr::null_mut(), core::ptr::null_mut()); + +pub(crate) static BLE_CONFIG: esp_bt_controller_config_t = esp_bt_controller_config_t { + config_version: 0x20230113, + ble_ll_resolv_list_size: 4, + ble_hci_evt_hi_buf_count: 30, + ble_hci_evt_lo_buf_count: 8, + ble_ll_sync_list_cnt: 5, + ble_ll_sync_cnt: 20, + ble_ll_rsp_dup_list_count: 20, + ble_ll_adv_dup_list_count: 20, + ble_ll_tx_pwr_dbm: 9, + rtc_freq: 32000, + ble_ll_sca: 60, + ble_ll_scan_phy_number: 1, + ble_ll_conn_def_auth_pyld_tmo: 3000, + ble_ll_jitter_usecs: 16, + ble_ll_sched_max_adv_pdu_usecs: 376, + ble_ll_sched_direct_adv_max_usecs: 502, + ble_ll_sched_adv_max_usecs: 852, + ble_scan_rsp_data_max_len: 31, + ble_ll_cfg_num_hci_cmd_pkts: 1, + ble_ll_ctrl_proc_timeout_ms: 40000, + nimble_max_connections: 2, + ble_whitelist_size: 12, + ble_acl_buf_size: 255, + ble_acl_buf_count: 24, + ble_hci_evt_buf_size: 70, + ble_multi_adv_instances: 1, + ble_ext_adv_max_size: 31, + controller_task_stack_size: 4096, + controller_task_prio: 253, // ??? + controller_run_cpu: 0, + enable_qa_test: 0, + enable_bqb_test: 0, + enable_uart_hci: 0, + ble_hci_uart_port: 0, + ble_hci_uart_baud: 0, + ble_hci_uart_data_bits: 0, + ble_hci_uart_stop_bits: 0, + ble_hci_uart_flow_ctrl: 0, + ble_hci_uart_uart_parity: 0, + enable_tx_cca: 0, + cca_rssi_thresh: (256 - 50) as u8, + sleep_en: 0, + coex_phy_coded_tx_rx_time_limit: 0, + dis_scan_backoff: 0, + ble_scan_classify_filter_enable: 1, + cca_drop_mode: 0, //??? + cca_low_tx_pwr: 0, //??? + main_xtal_freq: 32, + ignore_wl_for_direct_adv: 0, + config_magic: 0x5A5AA5A5, + + cpu_freq_mhz: 96, + enable_pcl: 0, + // version_num: 0, +}; + +pub(crate) fn bt_periph_module_enable() { + unsafe { + unwrap!(RADIO_CLOCKS.as_mut()).enable(RadioPeripherals::Bt); + } +} + +pub(crate) fn disable_sleep_mode() { + // nothing +} + +pub(super) unsafe extern "C" fn esp_intr_alloc( + source: u32, + flags: u32, + handler: *mut crate::binary::c_types::c_void, + arg: *mut crate::binary::c_types::c_void, + ret_handle: *mut *mut crate::binary::c_types::c_void, +) -> i32 { + debug!( + "esp_intr_alloc {} {} {:?} {:?} {:?}", + source, flags, handler, arg, ret_handle + ); + + match source { + 3 => ISR_INTERRUPT_3 = (handler, arg), + 15 => ISR_INTERRUPT_15 = (handler, arg), + _ => panic!("Unexpected interrupt source {}", source), + } + + 0 +} + +pub(super) fn ble_rtc_clk_init() { + unsafe { + unwrap!(RADIO_CLOCKS.as_mut()).ble_rtc_clk_init(); + } +} + +pub(super) unsafe extern "C" fn esp_reset_rpa_moudle() { + trace!("esp_reset_rpa_moudle"); + unsafe { + unwrap!(RADIO_CLOCKS.as_mut()).reset_rpa(); + } +} + +#[allow(improper_ctypes_definitions)] +#[no_mangle] +unsafe extern "C" fn jrand48( + _xsubi: [crate::binary::c_types::c_ushort; 3], +) -> crate::binary::c_types::c_long { + // this is not very random but good enough for now - it's apparently not used for crypto + unsafe { + static mut VALUE: u32 = 0; + VALUE = VALUE.wrapping_add(3); + VALUE as i32 + } +} diff --git a/esp-wifi/src/common_adapter/common_adapter_esp32h2.rs b/esp-wifi/src/common_adapter/common_adapter_esp32h2.rs new file mode 100644 index 00000000000..e23d033819c --- /dev/null +++ b/esp-wifi/src/common_adapter/common_adapter_esp32h2.rs @@ -0,0 +1,137 @@ +use super::phy_init_data::PHY_INIT_DATA_DEFAULT; +use crate::binary::include::*; +use crate::common_adapter::RADIO_CLOCKS; +use crate::compat::common::str_from_c; +use crate::hal::system::RadioClockController; +use crate::hal::system::RadioPeripherals; + +// use atomic_polyfill::AtomicU32; +use portable_atomic::{AtomicU32, Ordering}; + +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 mut PHY_ACCESS_REF: AtomicU32 = AtomicU32::new(0); + +pub(crate) fn enable_wifi_power_domain() { + // In esp-idf, SOC_PMU_SUPPORTED is set which makes `esp_wifi_bt_power_domain_on` + // a no-op. +} + +pub(crate) fn phy_mem_init() { + unsafe { + G_PHY_DIGITAL_REGS_MEM = SOC_PHY_DIG_REGS_MEM.as_ptr() as *mut u32; + } +} + +pub(crate) unsafe fn phy_enable() { + let count = PHY_ACCESS_REF.fetch_add(1, Ordering::SeqCst); + if count == 0 { + critical_section::with(|_| { + phy_enable_clock(); + + if G_IS_PHY_CALIBRATED == false { + let mut cal_data: [u8; core::mem::size_of::()] = + [0u8; core::mem::size_of::()]; + + let phy_version = get_phy_version_str(); + trace!("phy_version {}", str_from_c(phy_version as *const u8)); + + let init_data = &PHY_INIT_DATA_DEFAULT; + + #[cfg(feature = "phy-enable-usb")] + { + extern "C" { + pub fn phy_bbpll_en_usb(param: bool); + } + + phy_bbpll_en_usb(true); + } + 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(feature = "ble")] + { + extern "C" { + fn coex_pti_v2(); + } + coex_pti_v2(); + } + + 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(); + + // Disable PHY temperature sensor + phy_xpd_tsens(); + + // #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"); + unwrap!(RADIO_CLOCKS.as_mut()).enable(RadioPeripherals::Phy); + trace!("phy_enable_clock done!"); +} + +#[allow(unused)] +pub(crate) unsafe fn phy_disable_clock() { + trace!("phy_disable_clock"); + unwrap!(RADIO_CLOCKS.as_mut()).disable(RadioPeripherals::Phy); + trace!("phy_disable_clock done!"); +} + +#[no_mangle] +pub extern "C" fn rtc_clk_xtal_freq_get() -> i32 { + // JUST SUPPORT 32MHz XTAL for now + 32 +} diff --git a/esp-wifi/src/common_adapter/mod.rs b/esp-wifi/src/common_adapter/mod.rs index 849116c42e5..12b9c111317 100644 --- a/esp-wifi/src/common_adapter/mod.rs +++ b/esp-wifi/src/common_adapter/mod.rs @@ -18,6 +18,7 @@ use hal::macros::ram; #[cfg_attr(esp32c3, path = "common_adapter_esp32c3.rs")] #[cfg_attr(esp32c2, path = "common_adapter_esp32c2.rs")] #[cfg_attr(esp32c6, path = "common_adapter_esp32c6.rs")] +#[cfg_attr(esp32h2, path = "common_adapter_esp32h2.rs")] #[cfg_attr(esp32, path = "common_adapter_esp32.rs")] #[cfg_attr(esp32s3, path = "common_adapter_esp32s3.rs")] #[cfg_attr(esp32s2, path = "common_adapter_esp32s2.rs")] @@ -26,6 +27,7 @@ pub(crate) mod chip_specific; #[cfg_attr(esp32c3, path = "phy_init_data_esp32c3.rs")] #[cfg_attr(esp32c2, path = "phy_init_data_esp32c2.rs")] #[cfg_attr(esp32c6, path = "phy_init_data_esp32c6.rs")] +#[cfg_attr(esp32h2, path = "phy_init_data_esp32h2.rs")] #[cfg_attr(esp32, path = "phy_init_data_esp32.rs")] #[cfg_attr(esp32s3, path = "phy_init_data_esp32s3.rs")] #[cfg_attr(esp32s2, path = "phy_init_data_esp32s2.rs")] diff --git a/esp-wifi/src/common_adapter/phy_init_data_esp32h2.rs b/esp-wifi/src/common_adapter/phy_init_data_esp32h2.rs new file mode 100644 index 00000000000..d379b0bec99 --- /dev/null +++ b/esp-wifi/src/common_adapter/phy_init_data_esp32h2.rs @@ -0,0 +1,146 @@ +use crate::binary::include::esp_phy_init_data_t; + +const CONFIG_ESP_PHY_MAX_TX_POWER: u8 = 20; + +const fn limit(val: u8, low: u8, high: u8) -> u8 { + if val < low { + low + } else if val > high { + high + } else { + val + } +} + +pub(crate) static PHY_INIT_DATA_DEFAULT: esp_phy_init_data_t = esp_phy_init_data_t { + params: [ + 0x01, + 0x00, + limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x54), + limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x54), + limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x54), + limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x50), + limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x50), + limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x4c), + limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x4c), + limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x4c), + limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x4c), + limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x48), + limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x28), + limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x28), + limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x28), + limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x28), + limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x4c), + limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x4c), + limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x4c), + limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x4c), + limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x48), + limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x28), + limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x28), + limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x28), + limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x28), + 0x00, + 0x00, + 0x00, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0x9B, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], +}; diff --git a/esp-wifi/src/lib.rs b/esp-wifi/src/lib.rs index 36a270f8abc..9a4eb0e9b0e 100644 --- a/esp-wifi/src/lib.rs +++ b/esp-wifi/src/lib.rs @@ -24,12 +24,14 @@ use esp32c2_hal as hal; use esp32c3_hal as hal; #[cfg(esp32c6)] use esp32c6_hal as hal; +#[cfg(esp32h2)] +use esp32h2_hal as hal; #[cfg(esp32s2)] use esp32s2_hal as hal; #[cfg(esp32s3)] use esp32s3_hal as hal; -#[cfg(any(esp32c2, esp32c3, esp32c6))] +#[cfg(any(esp32c2, esp32c3, esp32c6, esp32h2))] use hal::systimer::{Alarm, Target}; use common_adapter::init_radio_clock_control; @@ -152,7 +154,7 @@ fn init_heap() { }); } -#[cfg(any(esp32c3, esp32c2, esp32c6))] +#[cfg(any(esp32c3, esp32c2, esp32c6, esp32h2))] pub(crate) type EspWifiTimer = Alarm; #[cfg(any(esp32, esp32s3, esp32s2))] @@ -245,6 +247,9 @@ pub fn initialize( #[cfg(esp32c2)] const MAX_CLOCK: u32 = 120; + #[cfg(esp32h2)] + const MAX_CLOCK: u32 = 96; + if clocks.cpu_clock != MegahertzU32::MHz(MAX_CLOCK) { return Err(InitializationError::WrongClockConfig); } diff --git a/esp-wifi/src/timer/mod.rs b/esp-wifi/src/timer/mod.rs index 4b1ce9bfab5..a0697ffe861 100644 --- a/esp-wifi/src/timer/mod.rs +++ b/esp-wifi/src/timer/mod.rs @@ -2,12 +2,13 @@ #[cfg_attr(esp32c2, path = "timer_esp32c2.rs")] #[cfg_attr(esp32c3, path = "timer_esp32c3.rs")] #[cfg_attr(esp32c6, path = "timer_esp32c6.rs")] +#[cfg_attr(esp32h2, path = "timer_esp32h2.rs")] #[cfg_attr(esp32s3, path = "timer_esp32s3.rs")] #[cfg_attr(esp32s2, path = "timer_esp32s2.rs")] mod chip_specific; #[cfg_attr(any(esp32, esp32s2, esp32s3), path = "xtensa.rs")] -#[cfg_attr(any(esp32c2, esp32c3, esp32c6), path = "riscv.rs")] +#[cfg_attr(any(esp32c2, esp32c3, esp32c6, esp32h2), path = "riscv.rs")] mod arch_specific; pub use arch_specific::*; diff --git a/esp-wifi/src/timer/riscv.rs b/esp-wifi/src/timer/riscv.rs index 53cf17c8cca..c74f80f7cf5 100644 --- a/esp-wifi/src/timer/riscv.rs +++ b/esp-wifi/src/timer/riscv.rs @@ -13,9 +13,9 @@ use crate::{ preempt::preempt::task_switch, }; -#[cfg(feature = "esp32c6")] +#[cfg(any(feature = "esp32c6", feature = "esp32h2"))] use peripherals::INTPRI as SystemPeripheral; -#[cfg(not(feature = "esp32c6"))] +#[cfg(not(any(feature = "esp32c6", feature = "esp32h2")))] use peripherals::SYSTEM as SystemPeripheral; /// The timer responsible for time slicing. diff --git a/esp-wifi/src/timer/timer_esp32h2.rs b/esp-wifi/src/timer/timer_esp32h2.rs new file mode 100644 index 00000000000..b77cd8131ce --- /dev/null +++ b/esp-wifi/src/timer/timer_esp32h2.rs @@ -0,0 +1,62 @@ +use crate::{ + binary, + hal::{interrupt, macros::interrupt, peripherals::Interrupt}, +}; + +pub fn setup_radio_isr() { + #[cfg(feature = "ble")] + { + unwrap!(interrupt::enable( + Interrupt::LP_BLE_TIMER, + interrupt::Priority::Priority1 + )); + unwrap!(interrupt::enable( + Interrupt::BT_MAC, + interrupt::Priority::Priority1 + )); + } +} + +#[cfg(feature = "ble")] +#[interrupt] +fn LP_BLE_TIMER() { + unsafe { + trace!("LP_TIMER interrupt"); + + let (fnc, arg) = crate::ble::npl::ble_os_adapter_chip_specific::ISR_INTERRUPT_3; + + trace!("interrupt LP_TIMER {:?} {:?}", fnc, arg); + + if !fnc.is_null() { + trace!("interrupt LP_TIMER call"); + + let fnc: fn(*mut binary::c_types::c_void) = core::mem::transmute(fnc); + fnc(arg); + trace!("LP_TIMER done"); + } + + trace!("interrupt LP_TIMER done"); + }; +} + +#[cfg(feature = "ble")] +#[interrupt] +fn BT_MAC() { + unsafe { + trace!("BT_MAC interrupt"); + + let (fnc, arg) = crate::ble::npl::ble_os_adapter_chip_specific::ISR_INTERRUPT_15; + + trace!("interrupt BT_MAC {:?} {:?}", fnc, arg); + + if !fnc.is_null() { + trace!("interrupt BT_MAC call"); + + let fnc: fn(*mut binary::c_types::c_void) = core::mem::transmute(fnc); + fnc(arg); + trace!("BT_MAC done"); + } + + trace!("interrupt BT_MAC done"); + }; +} diff --git a/esp-wifi/src/wifi/mod.rs b/esp-wifi/src/wifi/mod.rs index 1922880b5da..f5ec650d475 100644 --- a/esp-wifi/src/wifi/mod.rs +++ b/esp-wifi/src/wifi/mod.rs @@ -508,7 +508,7 @@ static g_wifi_osi_funcs: wifi_osi_funcs_t = wifi_osi_funcs_t { _coex_schm_interval_get: Some(coex_schm_interval_get), _coex_schm_curr_period_get: Some(coex_schm_curr_period_get), _coex_schm_curr_phase_get: Some(coex_schm_curr_phase_get), - #[cfg(any(esp32c3, esp32c2, esp32c6, esp32s3, esp32s2,))] + #[cfg(any(esp32c3, esp32c2, esp32c6, esp32h2, esp32s3, esp32s2))] _slowclk_cal_get: Some(slowclk_cal_get), #[cfg(any(esp32, esp32s2))] _phy_common_clock_disable: Some(os_adapter_chip_specific::phy_common_clock_disable), diff --git a/esp-wifi/src/wifi/os_adapter.rs b/esp-wifi/src/wifi/os_adapter.rs index 7b26e33c0c0..2afffa25e81 100644 --- a/esp-wifi/src/wifi/os_adapter.rs +++ b/esp-wifi/src/wifi/os_adapter.rs @@ -1,6 +1,7 @@ #[cfg_attr(esp32c3, path = "os_adapter_esp32c3.rs")] #[cfg_attr(esp32c2, path = "os_adapter_esp32c2.rs")] #[cfg_attr(esp32c6, path = "os_adapter_esp32c6.rs")] +#[cfg_attr(esp32h2, path = "os_adapter_esp32h2.rs")] #[cfg_attr(esp32, path = "os_adapter_esp32.rs")] #[cfg_attr(esp32s3, path = "os_adapter_esp32s3.rs")] #[cfg_attr(esp32s2, path = "os_adapter_esp32s2.rs")] @@ -2044,7 +2045,7 @@ pub unsafe extern "C" fn slowclk_cal_get() -> u32 { #[cfg(esp32c2)] return 28639; - #[cfg(esp32c6)] + #[cfg(any(esp32c6, esp32h2))] return 0; #[cfg(esp32)] diff --git a/esp-wifi/src/wifi/os_adapter_esp32h2.rs b/esp-wifi/src/wifi/os_adapter_esp32h2.rs new file mode 100644 index 00000000000..06ae1d5847f --- /dev/null +++ b/esp-wifi/src/wifi/os_adapter_esp32h2.rs @@ -0,0 +1,95 @@ +use crate::hal::{peripherals, riscv}; + +pub(crate) fn chip_ints_on(mask: u32) { + unsafe { + (*peripherals::INTPRI::PTR) + .cpu_int_enable + .modify(|r, w| w.bits(r.bits() | mask)); + } +} + +pub(crate) fn chip_ints_off(mask: u32) { + unsafe { + (*peripherals::INTPRI::PTR) + .cpu_int_enable + .modify(|r, w| w.bits(r.bits() & !mask)); + } +} + +pub(crate) unsafe extern "C" fn wifi_int_disable( + wifi_int_mux: *mut crate::binary::c_types::c_void, +) -> u32 { + let res = if riscv::register::mstatus::read().mie() { + 1 + } else { + 0 + }; + riscv::interrupt::disable(); + + trace!( + "wifi_int_disable wifi_int_mux {:?} - return {}", + wifi_int_mux, + res, + ); + + res +} + +pub(crate) unsafe extern "C" fn wifi_int_restore( + wifi_int_mux: *mut crate::binary::c_types::c_void, + tmp: u32, +) { + trace!( + "wifi_int_restore wifi_int_mux {:?} tmp {}", + wifi_int_mux, + tmp + ); + + if tmp == 1 { + riscv::interrupt::enable(); + } +} + +pub(crate) unsafe extern "C" fn set_intr( + _cpu_no: i32, + _intr_source: u32, + _intr_num: u32, + _intr_prio: i32, +) { + // this gets called with + // INFO - set_intr 0 2 1 1 (WIFI_PWR) + // INFO - set_intr 0 0 1 1 (WIFI_MAC) + + // we do nothing here since all the interrupts are already + // configured in `setup_timer_isr` and messing with the interrupts will + // get us into trouble +} + +pub(crate) unsafe extern "C" fn regdma_link_set_write_wait_content_dummy( + _arg1: *mut esp_wifi_sys::c_types::c_void, + _arg2: u32, + _arg3: u32, +) { + todo!() +} + +pub(crate) unsafe extern "C" fn sleep_retention_find_link_by_id_dummy( + _arg1: esp_wifi_sys::c_types::c_int, +) -> *mut esp_wifi_sys::c_types::c_void { + todo!() +} + +pub(crate) unsafe extern "C" fn sleep_retention_entries_create_dummy( + _arg1: *const esp_wifi_sys::c_types::c_void, + _arg2: esp_wifi_sys::c_types::c_int, + _arg3: esp_wifi_sys::c_types::c_int, + _arg4: esp_wifi_sys::c_types::c_int, +) -> esp_wifi_sys::c_types::c_int { + todo!() +} + +pub(crate) unsafe extern "C" fn sleep_retention_entries_destroy_dummy( + _arg1: esp_wifi_sys::c_types::c_int, +) { + todo!() +}