From b402692c72812614f56cb1ec35d0d3180a8b06b8 Mon Sep 17 00:00:00 2001 From: Jesse Braham Date: Thu, 14 Mar 2024 16:45:06 +0000 Subject: [PATCH] Create safe wrappers for some ROM functions in the `rom` module (#1290) * Create safe wrappers for some ROM functions in the `rom` module * Replace transmute in ESP32-S3's `cpu_control` module with ROM function * Inline *all* the things! * Remove duplicate of `rom::regi2c_write` with ROM function --- esp-hal/ld/esp32c6/rom-functions.x | 1 - esp-hal/ld/esp32h2/rom-functions.x | 3 +- esp-hal/ld/esp32s3/rom-functions.x | 3 +- esp-hal/src/analog/adc/riscv.rs | 7 +- esp-hal/src/clock/clocks_ll/esp32.rs | 280 ++++++++++--------------- esp-hal/src/clock/clocks_ll/esp32c2.rs | 11 +- esp-hal/src/clock/clocks_ll/esp32c3.rs | 11 +- esp-hal/src/clock/clocks_ll/esp32c6.rs | 32 ++- esp-hal/src/clock/clocks_ll/esp32h2.rs | 16 +- esp-hal/src/clock/clocks_ll/esp32p4.rs | 70 +++---- esp-hal/src/reset.rs | 7 +- esp-hal/src/rom/mod.rs | 58 +++++ esp-hal/src/rtc_cntl/mod.rs | 34 +-- esp-hal/src/rtc_cntl/rtc/esp32c6.rs | 35 +--- esp-hal/src/rtc_cntl/rtc/esp32h2.rs | 35 +--- esp-hal/src/soc/esp32s2/ulp_core.rs | 12 +- esp-hal/src/soc/esp32s3/cpu_control.rs | 9 +- esp-hal/src/soc/esp32s3/ulp_core.rs | 16 +- 18 files changed, 263 insertions(+), 377 deletions(-) diff --git a/esp-hal/ld/esp32c6/rom-functions.x b/esp-hal/ld/esp32c6/rom-functions.x index bc628237e1c..be855b250a2 100644 --- a/esp-hal/ld/esp32c6/rom-functions.x +++ b/esp-hal/ld/esp32c6/rom-functions.x @@ -1,5 +1,4 @@ ets_printf = 0x40000028; -ets_update_cpu_frequency = ets_update_cpu_frequency_rom; PROVIDE(esp_rom_printf = ets_printf); PROVIDE(cache_invalidate_icache_all = 0x4000064c); PROVIDE(cache_suspend_icache = 0x40000698); diff --git a/esp-hal/ld/esp32h2/rom-functions.x b/esp-hal/ld/esp32h2/rom-functions.x index 8318a51d24e..7f18124d528 100644 --- a/esp-hal/ld/esp32h2/rom-functions.x +++ b/esp-hal/ld/esp32h2/rom-functions.x @@ -1,5 +1,4 @@ ets_printf = 0x40000028; -ets_update_cpu_frequency = ets_update_cpu_frequency_rom; PROVIDE(esp_rom_printf = ets_printf); PROVIDE(cache_invalidate_icache_all = 0x40000620); PROVIDE(cache_suspend_icache = 0x4000066c); @@ -27,4 +26,4 @@ PROVIDE(esp_rom_md5_final = 0x40000720); memset = 0x400004a0; memcpy = 0x400004a4; memmove = 0x400004a8; -memcmp = 0x400004ac; \ No newline at end of file +memcmp = 0x400004ac; diff --git a/esp-hal/ld/esp32s3/rom-functions.x b/esp-hal/ld/esp32s3/rom-functions.x index 299d4d626d6..a909027ab5b 100644 --- a/esp-hal/ld/esp32s3/rom-functions.x +++ b/esp-hal/ld/esp32s3/rom-functions.x @@ -19,6 +19,7 @@ PROVIDE(Cache_Resume_DCache = 0x400018c0 ); PROVIDE(rom_config_data_cache_mode = 0x40001a28 ); PROVIDE(rom_config_instruction_cache_mode = 0x40001a1c ); PROVIDE(ets_efuse_get_wp_pad = 0x40001fa4); +PROVIDE(ets_set_appcpu_boot_addr = 0x40000720); PROVIDE(esp_rom_crc32_be = 0x40001ca4); PROVIDE(esp_rom_crc16_be = 0x40001cbc); @@ -38,4 +39,4 @@ PROVIDE( esp_rom_opiflash_pin_config = 0x40000894 ); memset = 0x400011e8; memcpy = 0x400011f4; memmove = 0x40001200; -memcmp = 0x4000120c; \ No newline at end of file +memcmp = 0x4000120c; diff --git a/esp-hal/src/analog/adc/riscv.rs b/esp-hal/src/analog/adc/riscv.rs index 5686731900d..406b24a4471 100644 --- a/esp-hal/src/analog/adc/riscv.rs +++ b/esp-hal/src/analog/adc/riscv.rs @@ -592,12 +592,7 @@ where // the delay might be a bit generous but longer delay seem to not cause problems #[cfg(esp32c6)] { - extern "C" { - fn ets_delay_us(us: u32); - } - unsafe { - ets_delay_us(40); - } + crate::rom::ets_delay_us(40); ADCI::start_onetime_sample(); } } diff --git a/esp-hal/src/clock/clocks_ll/esp32.rs b/esp-hal/src/clock/clocks_ll/esp32.rs index ec49774d524..fe3afc520d0 100644 --- a/esp-hal/src/clock/clocks_ll/esp32.rs +++ b/esp-hal/src/clock/clocks_ll/esp32.rs @@ -1,4 +1,7 @@ -use crate::clock::{Clock, PllClock, XtalClock}; +use crate::{ + clock::{Clock, PllClock, XtalClock}, + regi2c_write, +}; const REF_CLK_FREQ: u32 = 1000000; @@ -42,148 +45,108 @@ pub(crate) fn esp32_rtc_bbpll_configure(xtal_freq: XtalClock, pll_freq: PllClock let efuse = unsafe { &*crate::peripherals::EFUSE::ptr() }; let rtc_cntl = unsafe { &*crate::peripherals::RTC_CNTL::ptr() }; - unsafe { - let rtc_cntl_dbias_hp_volt: u32 = - RTC_CNTL_DBIAS_1V25 - efuse.blk0_rdata5().read().rd_vol_level_hp_inv().bits() as u32; - let dig_dbias_240_m: u32 = rtc_cntl_dbias_hp_volt; + let rtc_cntl_dbias_hp_volt: u32 = + RTC_CNTL_DBIAS_1V25 - efuse.blk0_rdata5().read().rd_vol_level_hp_inv().bits() as u32; + let dig_dbias_240_m: u32 = rtc_cntl_dbias_hp_volt; - let div_ref: u32; - let div7_0: u32; - let div10_8: u32; - let lref: u32; - let dcur: u32; - let bw: u32; - - if matches!(pll_freq, PllClock::Pll320MHz) { - // Raise the voltage, if needed - rtc_cntl - .reg() - .modify(|_, w| w.dig_dbias_wak().variant(DIG_DBIAS_80M_160M as u8)); - - // Configure 320M PLL - match xtal_freq { - XtalClock::RtcXtalFreq40M => { - div_ref = 0; - div7_0 = 32; - div10_8 = 0; - lref = 0; - dcur = 6; - bw = 3; - } - - XtalClock::RtcXtalFreq26M => { - div_ref = 12; - div7_0 = 224; - div10_8 = 4; - lref = 1; - dcur = 0; - bw = 1; - } - - XtalClock::RtcXtalFreqOther(_) => { - div_ref = 12; - div7_0 = 224; - div10_8 = 4; - lref = 0; - dcur = 0; - bw = 0; - } + let div_ref: u32; + let div7_0: u32; + let div10_8: u32; + let lref: u32; + let dcur: u32; + let bw: u32; + + if matches!(pll_freq, PllClock::Pll320MHz) { + // Raise the voltage, if needed + rtc_cntl + .reg() + .modify(|_, w| w.dig_dbias_wak().variant(DIG_DBIAS_80M_160M as u8)); + + // Configure 320M PLL + match xtal_freq { + XtalClock::RtcXtalFreq40M => { + div_ref = 0; + div7_0 = 32; + div10_8 = 0; + lref = 0; + dcur = 6; + bw = 3; } - i2c_writereg_rtc( - I2C_BBPLL, - I2C_BBPLL_HOSTID, - I2C_BBPLL_ENDIV5, - BBPLL_ENDIV5_VAL_320M, - ); - i2c_writereg_rtc( - I2C_BBPLL, - I2C_BBPLL_HOSTID, - I2C_BBPLL_BBADC_DSMP, - BBPLL_BBADC_DSMP_VAL_320M, - ); - } else { - // Raise the voltage - rtc_cntl - .reg() - .modify(|_, w| w.dig_dbias_wak().variant(dig_dbias_240_m as u8)); - - // Configure 480M PLL - match xtal_freq { - XtalClock::RtcXtalFreq40M => { - div_ref = 0; - div7_0 = 28; - div10_8 = 0; - lref = 0; - dcur = 6; - bw = 3; - } - - XtalClock::RtcXtalFreq26M => { - div_ref = 12; - div7_0 = 144; - div10_8 = 4; - lref = 1; - dcur = 0; - bw = 1; - } - - XtalClock::RtcXtalFreqOther(_) => { - div_ref = 12; - div7_0 = 224; - div10_8 = 4; - lref = 0; - dcur = 0; - bw = 0; - } + XtalClock::RtcXtalFreq26M => { + div_ref = 12; + div7_0 = 224; + div10_8 = 4; + lref = 1; + dcur = 0; + bw = 1; } - i2c_writereg_rtc( - I2C_BBPLL, - I2C_BBPLL_HOSTID, - I2C_BBPLL_ENDIV5, - BBPLL_ENDIV5_VAL_480M, - ); - - i2c_writereg_rtc( - I2C_BBPLL, - I2C_BBPLL_HOSTID, - I2C_BBPLL_BBADC_DSMP, - BBPLL_BBADC_DSMP_VAL_480M, - ); + XtalClock::RtcXtalFreqOther(_) => { + div_ref = 12; + div7_0 = 224; + div10_8 = 4; + lref = 0; + dcur = 0; + bw = 0; + } } - let i2c_bbpll_lref = (lref << 7) | (div10_8 << 4) | (div_ref); - let i2c_bbpll_div_7_0 = div7_0; - let i2c_bbpll_dcur = (bw << 6) | dcur; - i2c_writereg_rtc( - I2C_BBPLL, - I2C_BBPLL_HOSTID, - I2C_BBPLL_OC_LREF, - i2c_bbpll_lref, - ); - - i2c_writereg_rtc( - I2C_BBPLL, - I2C_BBPLL_HOSTID, - I2C_BBPLL_OC_DIV_7_0, - i2c_bbpll_div_7_0, - ); - - i2c_writereg_rtc( - I2C_BBPLL, - I2C_BBPLL_HOSTID, - I2C_BBPLL_OC_DCUR, - i2c_bbpll_dcur, - ); + regi2c_write!(I2C_BBPLL, I2C_BBPLL_ENDIV5, BBPLL_ENDIV5_VAL_320M); + regi2c_write!(I2C_BBPLL, I2C_BBPLL_BBADC_DSMP, BBPLL_BBADC_DSMP_VAL_320M); + } else { + // Raise the voltage + rtc_cntl + .reg() + .modify(|_, w| w.dig_dbias_wak().variant(dig_dbias_240_m as u8)); + + // Configure 480M PLL + match xtal_freq { + XtalClock::RtcXtalFreq40M => { + div_ref = 0; + div7_0 = 28; + div10_8 = 0; + lref = 0; + dcur = 6; + bw = 3; + } + + XtalClock::RtcXtalFreq26M => { + div_ref = 12; + div7_0 = 144; + div10_8 = 4; + lref = 1; + dcur = 0; + bw = 1; + } + + XtalClock::RtcXtalFreqOther(_) => { + div_ref = 12; + div7_0 = 224; + div10_8 = 4; + lref = 0; + dcur = 0; + bw = 0; + } + } + + regi2c_write!(I2C_BBPLL, I2C_BBPLL_ENDIV5, BBPLL_ENDIV5_VAL_480M); + regi2c_write!(I2C_BBPLL, I2C_BBPLL_BBADC_DSMP, BBPLL_BBADC_DSMP_VAL_480M); } + + let i2c_bbpll_lref = (lref << 7) | (div10_8 << 4) | (div_ref); + let i2c_bbpll_div_7_0 = div7_0; + let i2c_bbpll_dcur = (bw << 6) | dcur; + + regi2c_write!(I2C_BBPLL, I2C_BBPLL_OC_LREF, i2c_bbpll_lref); + regi2c_write!(I2C_BBPLL, I2C_BBPLL_OC_DIV_7_0, i2c_bbpll_div_7_0); + regi2c_write!(I2C_BBPLL, I2C_BBPLL_OC_DCUR, i2c_bbpll_dcur); } pub(crate) fn esp32_rtc_bbpll_enable() { - let rtc_cntl = unsafe { &*crate::peripherals::RTC_CNTL::ptr() }; - - unsafe { - rtc_cntl.options0().modify(|_, w| { + unsafe { &*crate::peripherals::RTC_CNTL::ptr() } + .options0() + .modify(|_, w| { w.bias_i2c_force_pd() .clear_bit() .bb_i2c_force_pd() @@ -194,49 +157,16 @@ pub(crate) fn esp32_rtc_bbpll_enable() { .clear_bit() }); - // reset BBPLL configuration - i2c_writereg_rtc( - I2C_BBPLL, - I2C_BBPLL_HOSTID, - I2C_BBPLL_IR_CAL_DELAY, - BBPLL_IR_CAL_DELAY_VAL, - ); - i2c_writereg_rtc( - I2C_BBPLL, - I2C_BBPLL_HOSTID, - I2C_BBPLL_IR_CAL_EXT_CAP, - BBPLL_IR_CAL_EXT_CAP_VAL, - ); - i2c_writereg_rtc( - I2C_BBPLL, - I2C_BBPLL_HOSTID, - I2C_BBPLL_OC_ENB_FCAL, - BBPLL_OC_ENB_FCAL_VAL, - ); - i2c_writereg_rtc( - I2C_BBPLL, - I2C_BBPLL_HOSTID, - I2C_BBPLL_OC_ENB_VCON, - BBPLL_OC_ENB_VCON_VAL, - ); - i2c_writereg_rtc( - I2C_BBPLL, - I2C_BBPLL_HOSTID, - I2C_BBPLL_BBADC_CAL_7_0, - BBPLL_BBADC_CAL_7_0_VAL, - ); - } -} - -#[inline(always)] -unsafe fn i2c_writereg_rtc(block: u32, block_hostid: u32, reg_add: u32, indata: u32) { - const ROM_I2C_WRITEREG: u32 = 0x400041a4; - - // cast to usize is just needed because of the way we run clippy in CI - let rom_i2c_writereg: fn(block: u32, block_hostid: u32, reg_add: u32, indata: u32) -> i32 = - core::mem::transmute(ROM_I2C_WRITEREG as usize); - - rom_i2c_writereg(block, block_hostid, reg_add, indata); + // reset BBPLL configuration + regi2c_write!(I2C_BBPLL, I2C_BBPLL_IR_CAL_DELAY, BBPLL_IR_CAL_DELAY_VAL); + regi2c_write!( + I2C_BBPLL, + I2C_BBPLL_IR_CAL_EXT_CAP, + BBPLL_IR_CAL_EXT_CAP_VAL + ); + regi2c_write!(I2C_BBPLL, I2C_BBPLL_OC_ENB_FCAL, BBPLL_OC_ENB_FCAL_VAL); + regi2c_write!(I2C_BBPLL, I2C_BBPLL_OC_ENB_VCON, BBPLL_OC_ENB_VCON_VAL); + regi2c_write!(I2C_BBPLL, I2C_BBPLL_BBADC_CAL_7_0, BBPLL_BBADC_CAL_7_0_VAL); } pub(crate) fn esp32_rtc_update_to_xtal(freq: XtalClock, _div: u32) { diff --git a/esp-hal/src/clock/clocks_ll/esp32c2.rs b/esp-hal/src/clock/clocks_ll/esp32c2.rs index 4098e3617cc..8efc143ad56 100644 --- a/esp-hal/src/clock/clocks_ll/esp32c2.rs +++ b/esp-hal/src/clock/clocks_ll/esp32c2.rs @@ -4,10 +4,6 @@ use crate::{ regi2c_write_mask, }; -extern "C" { - fn ets_update_cpu_frequency_rom(ticks_per_us: u32); -} - const I2C_BBPLL: u32 = 0x66; const I2C_BBPLL_HOSTID: u32 = 0; @@ -123,10 +119,10 @@ pub(crate) fn esp32c2_rtc_bbpll_enable() { } pub(crate) fn esp32c2_rtc_update_to_xtal(freq: XtalClock, _div: u32) { - let system_control = unsafe { &*crate::peripherals::SYSTEM::ptr() }; + crate::rom::ets_update_cpu_frequency_rom(freq.mhz()); + let system_control = unsafe { &*crate::peripherals::SYSTEM::ptr() }; unsafe { - ets_update_cpu_frequency_rom(freq.mhz()); // Set divider from XTAL to APB clock. Need to set divider to 1 (reg. value 0) // first. system_control.sysclk_conf().modify(|_, w| { @@ -158,8 +154,9 @@ pub(crate) fn esp32c2_rtc_freq_to_pll_mhz(cpu_clock_speed: CpuClock) { CpuClock::Clock120MHz => 1, }) }); - ets_update_cpu_frequency_rom(cpu_clock_speed.mhz()); } + + crate::rom::ets_update_cpu_frequency_rom(cpu_clock_speed.mhz()); } pub(crate) fn esp32c2_rtc_apb_freq_update(apb_freq: ApbClock) { diff --git a/esp-hal/src/clock/clocks_ll/esp32c3.rs b/esp-hal/src/clock/clocks_ll/esp32c3.rs index a943a28c58d..eca08b9a382 100644 --- a/esp-hal/src/clock/clocks_ll/esp32c3.rs +++ b/esp-hal/src/clock/clocks_ll/esp32c3.rs @@ -4,10 +4,6 @@ use crate::{ regi2c_write_mask, }; -extern "C" { - fn ets_update_cpu_frequency_rom(ticks_per_us: u32); -} - const I2C_BBPLL: u32 = 0x66; const I2C_BBPLL_HOSTID: u32 = 0; @@ -184,10 +180,10 @@ pub(crate) fn esp32c3_rtc_bbpll_enable() { } pub(crate) fn esp32c3_rtc_update_to_xtal(freq: XtalClock, _div: u32) { - let system_control = unsafe { &*crate::peripherals::SYSTEM::ptr() }; + crate::rom::ets_update_cpu_frequency_rom(freq.mhz()); + let system_control = unsafe { &*crate::peripherals::SYSTEM::ptr() }; unsafe { - ets_update_cpu_frequency_rom(freq.mhz()); // Set divider from XTAL to APB clock. Need to set divider to 1 (reg. value 0) // first. system_control.sysclk_conf().modify(|_, w| { @@ -219,8 +215,9 @@ pub(crate) fn esp32c3_rtc_freq_to_pll_mhz(cpu_clock_speed: CpuClock) { CpuClock::Clock160MHz => 1, }) }); - ets_update_cpu_frequency_rom(cpu_clock_speed.mhz()); } + + crate::rom::ets_update_cpu_frequency_rom(cpu_clock_speed.mhz()); } pub(crate) fn esp32c3_rtc_apb_freq_update(apb_freq: ApbClock) { diff --git a/esp-hal/src/clock/clocks_ll/esp32c6.rs b/esp-hal/src/clock/clocks_ll/esp32c6.rs index df784690761..e6d2f585c28 100644 --- a/esp-hal/src/clock/clocks_ll/esp32c6.rs +++ b/esp-hal/src/clock/clocks_ll/esp32c6.rs @@ -7,10 +7,6 @@ use crate::{ rtc_cntl::rtc::CpuClockSource, }; -extern "C" { - fn ets_update_cpu_frequency(ticks_per_us: u32); -} - const I2C_BBPLL: u8 = 0x66; const I2C_BBPLL_HOSTID: u8 = 0; @@ -248,21 +244,21 @@ pub(crate) fn esp32c6_rtc_update_to_xtal(freq: XtalClock, div: u8) { } pub(crate) fn esp32c6_rtc_update_to_xtal_raw(freq_mhz: u32, div: u8) { - unsafe { - esp32c6_ahb_set_ls_divider(div); - esp32c6_cpu_set_ls_divider(div); - CpuClockSource::Xtal.select(); - ets_update_cpu_frequency(freq_mhz); - } + esp32c6_ahb_set_ls_divider(div); + esp32c6_cpu_set_ls_divider(div); + + CpuClockSource::Xtal.select(); + + crate::rom::ets_update_cpu_frequency_rom(freq_mhz); } pub(crate) fn esp32c6_rtc_update_to_8m() { - unsafe { - esp32c6_ahb_set_ls_divider(1); - esp32c6_cpu_set_ls_divider(1); - CpuClockSource::RcFast.select(); - ets_update_cpu_frequency(20); - } + esp32c6_ahb_set_ls_divider(1); + esp32c6_cpu_set_ls_divider(1); + + CpuClockSource::RcFast.select(); + + crate::rom::ets_update_cpu_frequency_rom(20); } pub(crate) fn esp32c6_rtc_freq_to_pll_mhz(cpu_clock_speed: CpuClock) { @@ -289,9 +285,9 @@ pub(crate) fn esp32c6_rtc_freq_to_pll_mhz_raw(cpu_clock_speed_mhz: u32) { .modify(|_, w| w.cpu_hs_120m_force().clear_bit()); CpuClockSource::Pll.select(); - - ets_update_cpu_frequency(cpu_clock_speed_mhz); } + + crate::rom::ets_update_cpu_frequency_rom(cpu_clock_speed_mhz); } pub(crate) fn esp32c6_rtc_apb_freq_update(apb_freq: ApbClock) { diff --git a/esp-hal/src/clock/clocks_ll/esp32h2.rs b/esp-hal/src/clock/clocks_ll/esp32h2.rs index d2fe6d87cfa..311fc6ea9d1 100644 --- a/esp-hal/src/clock/clocks_ll/esp32h2.rs +++ b/esp-hal/src/clock/clocks_ll/esp32h2.rs @@ -1,9 +1,5 @@ use crate::clock::{ApbClock, Clock, CpuClock, PllClock, XtalClock}; -extern "C" { - fn ets_update_cpu_frequency(ticks_per_us: u32); -} - const I2C_BBPLL: u8 = 0x66; const I2C_BBPLL_HOSTID: u8 = 0; const I2C_BBPLL_OC_REF_DIV: u8 = 2; @@ -165,7 +161,7 @@ pub(crate) fn esp32h2_rtc_bbpll_enable() { pub(crate) fn esp32h2_rtc_update_to_xtal(freq: XtalClock, _div: u8) { unsafe { let pcr = &*crate::peripherals::PCR::PTR; - ets_update_cpu_frequency(freq.mhz()); + crate::rom::ets_update_cpu_frequency_rom(freq.mhz()); // Set divider from XTAL to APB clock. Need to set divider to 1 (reg. value 0) // first. clk_ll_ahb_set_divider(_div as u32); @@ -189,15 +185,15 @@ pub(crate) fn esp32h2_rtc_freq_to_pll_mhz(cpu_clock_speed: CpuClock) { }; clk_ll_ahb_set_divider(ahb_divider); - let pcr = unsafe { &*crate::peripherals::PCR::PTR }; - unsafe { - pcr.sysclk_conf().modify(|_, w| w.soc_clk_sel().bits(1)); + (*crate::peripherals::PCR::PTR) + .sysclk_conf() + .modify(|_, w| w.soc_clk_sel().bits(1)); clk_ll_bus_update(); - - ets_update_cpu_frequency(cpu_clock_speed.mhz()); } + + crate::rom::ets_update_cpu_frequency_rom(cpu_clock_speed.mhz()); } pub(crate) fn esp32h2_rtc_apb_freq_update(apb_freq: ApbClock) { diff --git a/esp-hal/src/clock/clocks_ll/esp32p4.rs b/esp-hal/src/clock/clocks_ll/esp32p4.rs index 0c28b61ae68..2f4544e752b 100644 --- a/esp-hal/src/clock/clocks_ll/esp32p4.rs +++ b/esp-hal/src/clock/clocks_ll/esp32p4.rs @@ -1,11 +1,5 @@ use crate::clock::{Clock, CpuClock, PllClock, XtalClock}; -extern "C" { - fn ets_update_cpu_frequency(ticks_per_us: u32); - fn ets_delay_us(delay: u32); - -} - const DR_REG_LPAON_BASE: u32 = 0x50110000; const DR_REG_LP_SYS_BASE: u32 = DR_REG_LPAON_BASE + 0x0; const DR_REG_LPPERIPH_BASE: u32 = 0x50120000; @@ -157,9 +151,7 @@ pub(crate) fn esp32p4_rtc_cpll_configure(xtal_freq: XtalClock, cpll_freq: PllClo ) == 1 {} - unsafe { - ets_delay_us(10); - } + crate::rom::ets_delay_us(10); // CPLL calibration stop set_peri_reg_mask( @@ -190,49 +182,45 @@ pub(crate) fn esp32p4_rtc_update_to_xtal(freq: XtalClock, div: u8, default: bool // clk_tree_ll.h(comp/hal/p4/include/hal/L407) assert!(div >= 1 && (div as u32) < HP_SYS_CLKRST_REG_CPU_CLK_DIV_NUM_V); - // Set CPU divider + let hp_sys_clkrst = unsafe { &*crate::soc::peripherals::HP_SYS_CLKRST::PTR }; unsafe { - (&*crate::soc::peripherals::HP_SYS_CLKRST::PTR) - .root_clk_ctrl0() - .modify(|_, w| w.cpu_clk_div_num().bits(div - 1)); - - (&*crate::soc::peripherals::HP_SYS_CLKRST::PTR) - .root_clk_ctrl0() - .modify(|_, w| w.cpu_clk_div_numerator().bits(0)); - - (&*crate::soc::peripherals::HP_SYS_CLKRST::PTR) - .root_clk_ctrl0() - .modify(|_, w| w.cpu_clk_div_denominator().bits(0)); - - // Set memory divider - (&*crate::soc::peripherals::HP_SYS_CLKRST::PTR) - .root_clk_ctrl1() - .modify(|_, w| w.mem_clk_div_num().bits((mem_divider - 1) as u8)); - - // Set system divider - (&*crate::soc::peripherals::HP_SYS_CLKRST::PTR) - .root_clk_ctrl1() - .modify(|_, w| w.sys_clk_div_num().bits((sys_divider - 1) as u8)); - - // Set APB divider - (&*crate::soc::peripherals::HP_SYS_CLKRST::PTR) + // Set CPU divider: + hp_sys_clkrst.root_clk_ctrl0().modify(|_, w| { + w.cpu_clk_div_num() + .bits(div - 1) + .cpu_clk_div_numerator() + .bits(0) + .cpu_clk_div_denominator() + .bits(0) + }); + + // Set memory and system dividers: + hp_sys_clkrst.root_clk_ctrl1().modify(|_, w| { + w.mem_clk_div_num() + .bits((mem_divider - 1) as u8) + .sys_clk_div_num() + .bits((sys_divider - 1) as u8) + }); + + // Set APB divider: + hp_sys_clkrst .root_clk_ctrl2() .modify(|_, w| w.apb_clk_div_num().bits((apb_divider - 1) as u8)); - // Bus update - (&*crate::soc::peripherals::HP_SYS_CLKRST::PTR) + // Bus update: + hp_sys_clkrst .root_clk_ctrl0() .modify(|_, w| w.soc_clk_div_update().set_bit()); - while (&*crate::soc::peripherals::HP_SYS_CLKRST::PTR) + while hp_sys_clkrst .root_clk_ctrl0() .read() .soc_clk_div_update() .bit_is_set() {} - - ets_update_cpu_frequency(freq.mhz()); } + + crate::rom::ets_update_cpu_frequency_rom(freq.mhz()); } // esp_rom_regi2c_esp32p4.c (L84) @@ -383,9 +371,9 @@ pub(crate) fn esp32p4_rtc_freq_to_cpll_mhz(cpu_clock_speed: CpuClock) { (&*crate::soc::peripherals::HP_SYS_CLKRST::PTR) .root_clk_ctrl0() .modify(|_, w| w.soc_clk_div_update().set_bit()); - - ets_update_cpu_frequency(cpu_clock_speed.mhz()); } + + crate::rom::ets_update_cpu_frequency_rom(cpu_clock_speed.mhz()); } fn regi2c_disable_block(block: u8) { diff --git a/esp-hal/src/reset.rs b/esp-hal/src/reset.rs index 3402f2ed355..d50947f1d15 100644 --- a/esp-hal/src/reset.rs +++ b/esp-hal/src/reset.rs @@ -104,17 +104,20 @@ bitflags::bitflags! { /// Performs a software reset on the chip. pub fn software_reset() { - unsafe { crate::rtc_cntl::software_reset() } + crate::rom::software_reset(); } + /// Performs a software reset on the CPU. pub fn software_reset_cpu() { - unsafe { crate::rtc_cntl::software_reset_cpu() } + crate::rom::software_reset_cpu(); } + /// Retrieves the reason for the last reset as a SocResetReason enum value. /// Returns `None` if the reset reason cannot be determined. pub fn get_reset_reason() -> Option { crate::rtc_cntl::get_reset_reason(crate::get_core()) } + /// Retrieves the cause of the last wakeup event as a SleepSource enum value. pub fn get_wakeup_cause() -> SleepSource { crate::rtc_cntl::get_wakeup_cause() diff --git a/esp-hal/src/rom/mod.rs b/esp-hal/src/rom/mod.rs index 8137ca028eb..5e4429f94ba 100644 --- a/esp-hal/src/rom/mod.rs +++ b/esp-hal/src/rom/mod.rs @@ -23,6 +23,8 @@ //! [CRC (Cyclic Redundancy Check)]: ./crc/index.html //! [MD5 (Message Digest 5)]: ./md5/index.html +#![allow(unused_macros)] + #[cfg(any(rom_crc_be, rom_crc_le))] pub mod crc; #[cfg(any(rom_md5_bsd, rom_md5_mbedtls))] @@ -79,3 +81,59 @@ macro_rules! regi2c_write_mask { } }; } + +#[inline(always)] +pub(crate) fn ets_delay_us(us: u32) { + extern "C" { + fn ets_delay_us(us: u32); + } + + unsafe { ets_delay_us(us) }; +} + +#[allow(unused)] +#[inline(always)] +pub(crate) fn ets_update_cpu_frequency_rom(ticks_per_us: u32) { + extern "C" { + fn ets_update_cpu_frequency_rom(ticks_per_us: u32); + } + + unsafe { ets_update_cpu_frequency_rom(ticks_per_us) }; +} + +#[inline(always)] +pub(crate) fn rtc_get_reset_reason(cpu_num: u32) -> u32 { + extern "C" { + fn rtc_get_reset_reason(cpu_num: u32) -> u32; + } + + unsafe { rtc_get_reset_reason(cpu_num) } +} + +#[inline(always)] +pub(crate) fn software_reset_cpu() { + extern "C" { + fn software_reset_cpu(); + } + + unsafe { software_reset_cpu() }; +} + +#[inline(always)] +pub(crate) fn software_reset() { + extern "C" { + fn software_reset(); + } + + unsafe { software_reset() }; +} + +#[cfg(esp32s3)] +#[inline(always)] +pub(crate) fn ets_set_appcpu_boot_addr(boot_addr: u32) { + extern "C" { + fn ets_set_appcpu_boot_addr(boot_addr: u32); + } + + unsafe { ets_set_appcpu_boot_addr(boot_addr) }; +} diff --git a/esp-hal/src/rtc_cntl/mod.rs b/esp-hal/src/rtc_cntl/mod.rs index 10555ba7f8d..b72a9387ab2 100644 --- a/esp-hal/src/rtc_cntl/mod.rs +++ b/esp-hal/src/rtc_cntl/mod.rs @@ -106,14 +106,6 @@ pub(crate) mod rtc; #[cfg(any(esp32c6, esp32h2))] pub use rtc::RtcClock; -extern "C" { - #[allow(dead_code)] - fn ets_delay_us(us: u32); - fn rtc_get_reset_reason(cpu_num: u32) -> u32; - pub fn software_reset_cpu(); - pub fn software_reset(); -} - #[cfg(not(any(esp32c6, esp32h2)))] #[allow(unused)] #[derive(Debug, Clone, Copy)] @@ -227,10 +219,8 @@ impl<'d> Rtc<'d> { let (l, h) = { rtc_cntl.time_update().write(|w| w.time_update().set_bit()); while rtc_cntl.time_update().read().time_valid().bit_is_clear() { - unsafe { - // might take 1 RTC slowclk period, don't flood RTC bus - ets_delay_us(1); - } + // might take 1 RTC slowclk period, don't flood RTC bus + crate::rom::ets_delay_us(1); } let h = rtc_cntl.time1().read().time_hi().bits(); let l = rtc_cntl.time0().read().time_lo().bits(); @@ -342,8 +332,8 @@ impl RtcClock { rtc_cntl.clk_conf().modify(|_, w| w.enb_ck8m().clear_bit()); unsafe { rtc_cntl.timer1().modify(|_, w| w.ck8m_wait().bits(5)); - ets_delay_us(50); } + crate::rom::ets_delay_us(50); } else { rtc_cntl.clk_conf().modify(|_, w| w.enb_ck8m().set_bit()); rtc_cntl @@ -421,9 +411,9 @@ impl RtcClock { .ck8m_force_pu() .bit(matches!(slow_freq, RtcSlowClock::RtcSlowClock8mD256)) }); - - ets_delay_us(300u32); }; + + crate::rom::ets_delay_us(300u32); } /// Select source for RTC_FAST_CLK @@ -437,9 +427,9 @@ impl RtcClock { RtcFastClock::RtcFastClockXtalD4 => false, }) }); - - ets_delay_us(3u32); }; + + crate::rom::ets_delay_us(3u32); } /// Calibration of RTC_SLOW_CLK is performed using a special feature of @@ -544,9 +534,7 @@ impl RtcClock { .modify(|_, w| w.rtc_cali_start().clear_bit().rtc_cali_start().set_bit()); // Wait for calibration to finish up to another us_time_estimate - unsafe { - ets_delay_us(us_time_estimate); - } + crate::rom::ets_delay_us(us_time_estimate); #[cfg(esp32)] let mut timeout_us = us_time_estimate; @@ -565,9 +553,7 @@ impl RtcClock { #[cfg(esp32)] if timeout_us > 0 { timeout_us -= 1; - unsafe { - ets_delay_us(1); - } + crate::rom::ets_delay_us(1); } else { // Timed out waiting for calibration break 0; @@ -960,7 +946,7 @@ impl embedded_hal_02::watchdog::WatchdogDisable for Swd { } pub fn get_reset_reason(cpu: Cpu) -> Option { - let reason = unsafe { rtc_get_reset_reason(cpu as u32) }; + let reason = crate::rom::rtc_get_reset_reason(cpu as u32); SocResetReason::from_repr(reason as usize) } diff --git a/esp-hal/src/rtc_cntl/rtc/esp32c6.rs b/esp-hal/src/rtc_cntl/rtc/esp32c6.rs index 87d97b7b355..6dc3891fb10 100644 --- a/esp-hal/src/rtc_cntl/rtc/esp32c6.rs +++ b/esp-hal/src/rtc_cntl/rtc/esp32c6.rs @@ -1350,10 +1350,6 @@ pub enum SocResetReason { Cpu0JtagCpu = 0x18, } -extern "C" { - fn ets_delay_us(us: u32); -} - #[allow(unused)] #[derive(Debug, Clone, Copy)] /// RTC SLOW_CLK frequency values @@ -1498,8 +1494,9 @@ impl RtcClock { RtcFastClock::RtcFastClockXtalD2 => true, }) }); - ets_delay_us(3); } + + crate::rom::ets_delay_us(3); } /// Calibration of RTC_SLOW_CLK is performed using a special feature of @@ -1602,18 +1599,14 @@ impl RtcClock { if !rc_fast_enabled { pmu.hp_sleep_lp_ck_power() .modify(|_, w| w.hp_sleep_xpd_fosc_clk().set_bit()); - unsafe { - ets_delay_us(50); - } + crate::rom::ets_delay_us(50); } if !dig_rc_fast_enabled { lp_clkrst .clk_to_hp() .modify(|_, w| w.icg_hp_fosc().set_bit()); - unsafe { - ets_delay_us(5); - } + crate::rom::ets_delay_us(5); } } @@ -1628,9 +1621,7 @@ impl RtcClock { if !rc32k_enabled { pmu.hp_sleep_lp_ck_power() .modify(|_, w| w.hp_sleep_xpd_rc32k().set_bit()); - unsafe { - ets_delay_us(300); - } + crate::rom::ets_delay_us(300); } if !dig_rc32k_enabled { @@ -1705,9 +1696,7 @@ impl RtcClock { .modify(|_, w| w.rtc_cali_start().set_bit()); // Wait for calibration to finish up to another us_time_estimate - unsafe { - ets_delay_us(us_time_estimate); - } + crate::rom::ets_delay_us(us_time_estimate); let cal_val = loop { if timg0.rtccalicfg().read().rtc_cali_rdy().bit_is_set() { @@ -1746,18 +1735,14 @@ impl RtcClock { if rc_fast_enabled { pmu.hp_sleep_lp_ck_power() .modify(|_, w| w.hp_sleep_xpd_fosc_clk().set_bit()); - unsafe { - ets_delay_us(50); - } + crate::rom::ets_delay_us(50); } if dig_rc_fast_enabled { lp_clkrst .clk_to_hp() .modify(|_, w| w.icg_hp_fosc().set_bit()); - unsafe { - ets_delay_us(5); - } + crate::rom::ets_delay_us(5); } } @@ -1765,9 +1750,7 @@ impl RtcClock { if rc32k_enabled { pmu.hp_sleep_lp_ck_power() .modify(|_, w| w.hp_sleep_xpd_rc32k().set_bit()); - unsafe { - ets_delay_us(300); - } + crate::rom::ets_delay_us(300); } if dig_rc32k_enabled { lp_clkrst diff --git a/esp-hal/src/rtc_cntl/rtc/esp32h2.rs b/esp-hal/src/rtc_cntl/rtc/esp32h2.rs index aa5771cc229..01e4eee0567 100644 --- a/esp-hal/src/rtc_cntl/rtc/esp32h2.rs +++ b/esp-hal/src/rtc_cntl/rtc/esp32h2.rs @@ -221,10 +221,6 @@ impl Clock for RtcFastClock { } } -extern "C" { - fn ets_delay_us(us: u32); -} - /// RTC SLOW_CLK frequency values #[allow(clippy::enum_variant_names)] #[derive(Debug, Clone, Copy, PartialEq)] @@ -314,8 +310,9 @@ impl RtcClock { RtcFastClock::RtcFastClockXtalD2 => 0b01, }) }); - ets_delay_us(3); } + + crate::rom::ets_delay_us(3); } fn set_slow_freq(slow_freq: RtcSlowClock) { @@ -457,18 +454,14 @@ impl RtcClock { if !rc_fast_enabled { pmu.hp_sleep_lp_ck_power() .modify(|_, w| w.hp_sleep_xpd_fosc_clk().set_bit()); - unsafe { - ets_delay_us(50); - } + crate::rom::ets_delay_us(50); } if !dig_rc_fast_enabled { lp_clkrst .clk_to_hp() .modify(|_, w| w.icg_hp_fosc().set_bit()); - unsafe { - ets_delay_us(5); - } + crate::rom::ets_delay_us(5); } } @@ -483,9 +476,7 @@ impl RtcClock { if !rc32k_enabled { pmu.hp_sleep_lp_ck_power() .modify(|_, w| w.hp_sleep_xpd_rc32k().set_bit()); - unsafe { - ets_delay_us(300); - } + crate::rom::ets_delay_us(300); } if !dig_rc32k_enabled { @@ -560,9 +551,7 @@ impl RtcClock { .modify(|_, w| w.rtc_cali_start().set_bit()); // Wait for calibration to finish up to another us_time_estimate - unsafe { - ets_delay_us(us_time_estimate); - } + crate::rom::ets_delay_us(us_time_estimate); let cal_val = loop { if timg0.rtccalicfg().read().rtc_cali_rdy().bit_is_set() { @@ -589,18 +578,14 @@ impl RtcClock { if rc_fast_enabled { pmu.hp_sleep_lp_ck_power() .modify(|_, w| w.hp_sleep_xpd_fosc_clk().set_bit()); - unsafe { - ets_delay_us(50); - } + crate::rom::ets_delay_us(50); } if dig_rc_fast_enabled { lp_clkrst .clk_to_hp() .modify(|_, w| w.icg_hp_fosc().set_bit()); - unsafe { - ets_delay_us(5); - } + crate::rom::ets_delay_us(5); } } @@ -608,9 +593,7 @@ impl RtcClock { if rc32k_enabled { pmu.hp_sleep_lp_ck_power() .modify(|_, w| w.hp_sleep_xpd_rc32k().set_bit()); - unsafe { - ets_delay_us(300); - } + crate::rom::ets_delay_us(300); } if dig_rc32k_enabled { lp_clkrst diff --git a/esp-hal/src/soc/esp32s2/ulp_core.rs b/esp-hal/src/soc/esp32s2/ulp_core.rs index de2b4ae33fa..0cf540bf8a7 100644 --- a/esp-hal/src/soc/esp32s2/ulp_core.rs +++ b/esp-hal/src/soc/esp32s2/ulp_core.rs @@ -40,10 +40,6 @@ use esp32s2 as pac; use crate::peripheral::{Peripheral, PeripheralRef}; -extern "C" { - fn ets_delay_us(delay: u32); -} - #[derive(Debug, Clone, Copy)] pub enum UlpCoreWakeupSource { HpCpu, @@ -109,9 +105,7 @@ fn ulp_run(wakeup_src: UlpCoreWakeupSource) { .modify(|_, w| w.ulp_cp_slp_timer_en().clear_bit()); // wait for at least 1 RTC_SLOW_CLK cycle - unsafe { - ets_delay_us(20); - } + crate::rom::ets_delay_us(20); // Select ULP-RISC-V to send the DONE signal rtc_cntl @@ -126,9 +120,7 @@ fn ulp_run(wakeup_src: UlpCoreWakeupSource) { .modify(|_, w| w.cocpu_sel().clear_bit()); // Clear any spurious wakeup trigger interrupts upon ULP startup - unsafe { - ets_delay_us(20); - } + crate::rom::ets_delay_us(20); rtc_cntl.int_clr_rtc().write(|w| { w.cocpu_int_clr() diff --git a/esp-hal/src/soc/esp32s3/cpu_control.rs b/esp-hal/src/soc/esp32s3/cpu_control.rs index 62025e096d4..4ff0f87a0ea 100644 --- a/esp-hal/src/soc/esp32s3/cpu_control.rs +++ b/esp-hal/src/soc/esp32s3/cpu_control.rs @@ -293,14 +293,7 @@ impl CpuControl { APP_CORE_STACK_TOP = Some(stack.top()); } - // TODO there is no boot_addr register in SVD or TRM - ESP-IDF uses a ROM - // function so we also have to for now - const ETS_SET_APPCPU_BOOT_ADDR: usize = 0x40000720; - unsafe { - let ets_set_appcpu_boot_addr: unsafe extern "C" fn(u32) = - core::mem::transmute(ETS_SET_APPCPU_BOOT_ADDR); - ets_set_appcpu_boot_addr(Self::start_core1_init:: as *const u32 as u32); - }; + crate::rom::ets_set_appcpu_boot_addr(Self::start_core1_init:: as *const u32 as u32); system_control .core_1_control_0() diff --git a/esp-hal/src/soc/esp32s3/ulp_core.rs b/esp-hal/src/soc/esp32s3/ulp_core.rs index d38ab4456aa..3026f273ab2 100644 --- a/esp-hal/src/soc/esp32s3/ulp_core.rs +++ b/esp-hal/src/soc/esp32s3/ulp_core.rs @@ -41,10 +41,6 @@ use esp32s3 as pac; use crate::peripheral::{Peripheral, PeripheralRef}; -extern "C" { - fn ets_delay_us(delay: u32); -} - #[derive(Debug, Clone, Copy)] pub enum UlpCoreWakeupSource { HpCpu, @@ -94,9 +90,7 @@ fn ulp_stop() { .cocpu_ctrl() .modify(|_, w| w.cocpu_shut_reset_en().set_bit()); - unsafe { - ets_delay_us(20); - } + crate::rom::ets_delay_us(20); // above doesn't seem to halt the ULP core - this will rtc_cntl @@ -124,9 +118,7 @@ fn ulp_run(wakeup_src: UlpCoreWakeupSource) { .modify(|_, w| w.ulp_cp_slp_timer_en().clear_bit()); // wait for at least 1 RTC_SLOW_CLK cycle - unsafe { - ets_delay_us(20); - } + crate::rom::ets_delay_us(20); // We do not select RISC-V as the Coprocessor here as this could lead to a hang // in the main CPU. Instead, we reset RTC_CNTL_COCPU_SEL after we have enabled @@ -154,9 +146,7 @@ fn ulp_run(wakeup_src: UlpCoreWakeupSource) { .modify(|_, w| w.cocpu_sel().clear_bit()); // Clear any spurious wakeup trigger interrupts upon ULP startup - unsafe { - ets_delay_us(20); - } + crate::rom::ets_delay_us(20); rtc_cntl.int_clr_rtc().write(|w| { w.cocpu_int_clr()