diff --git a/esp-hal/Cargo.toml b/esp-hal/Cargo.toml index 1fca7c2e53..fe23456688 100644 --- a/esp-hal/Cargo.toml +++ b/esp-hal/Cargo.toml @@ -57,13 +57,13 @@ ufmt-write = "0.1.0" # IMPORTANT: # Each supported device MUST have its PAC included below along with a # corresponding feature. -esp32 = { version = "0.35.0", features = ["critical-section", "rt"], git = "https://github.com/esp-rs/esp-pacs", rev = "cab435a", optional = true } -esp32c2 = { version = "0.24.0", features = ["critical-section", "rt"], git = "https://github.com/esp-rs/esp-pacs", rev = "cab435a", optional = true } -esp32c3 = { version = "0.27.0", features = ["critical-section", "rt"], git = "https://github.com/esp-rs/esp-pacs", rev = "cab435a", optional = true } -esp32c6 = { version = "0.18.0", features = ["critical-section", "rt"], git = "https://github.com/esp-rs/esp-pacs", rev = "cab435a", optional = true } -esp32h2 = { version = "0.14.0", features = ["critical-section", "rt"], git = "https://github.com/esp-rs/esp-pacs", rev = "cab435a", optional = true } -esp32s2 = { version = "0.26.0", features = ["critical-section", "rt"], git = "https://github.com/esp-rs/esp-pacs", rev = "cab435a", optional = true } -esp32s3 = { version = "0.30.0", features = ["critical-section", "rt"], git = "https://github.com/esp-rs/esp-pacs", rev = "cab435a", optional = true } +esp32 = { version = "0.35.0", features = ["critical-section", "rt"], git = "https://github.com/esp-rs/esp-pacs", rev = "448410158", optional = true } +esp32c2 = { version = "0.24.0", features = ["critical-section", "rt"], git = "https://github.com/esp-rs/esp-pacs", rev = "448410158", optional = true } +esp32c3 = { version = "0.27.0", features = ["critical-section", "rt"], git = "https://github.com/esp-rs/esp-pacs", rev = "448410158", optional = true } +esp32c6 = { version = "0.18.0", features = ["critical-section", "rt"], git = "https://github.com/esp-rs/esp-pacs", rev = "448410158", optional = true } +esp32h2 = { version = "0.14.0", features = ["critical-section", "rt"], git = "https://github.com/esp-rs/esp-pacs", rev = "448410158", optional = true } +esp32s2 = { version = "0.26.0", features = ["critical-section", "rt"], git = "https://github.com/esp-rs/esp-pacs", rev = "448410158", optional = true } +esp32s3 = { version = "0.30.0", features = ["critical-section", "rt"], git = "https://github.com/esp-rs/esp-pacs", rev = "448410158", optional = true } [target.'cfg(target_arch = "riscv32")'.dependencies] riscv = { version = "0.12.1" } diff --git a/esp-hal/src/clock/clocks_ll/esp32.rs b/esp-hal/src/clock/clocks_ll/esp32.rs index b633fe5c62..aab188ad50 100644 --- a/esp-hal/src/clock/clocks_ll/esp32.rs +++ b/esp-hal/src/clock/clocks_ll/esp32.rs @@ -1,6 +1,6 @@ use crate::{ clock::{Clock, PllClock, XtalClock}, - peripherals::DPORT, + peripherals::{APB_CTRL, DPORT, EFUSE, LPWR}, rom::regi2c_write, }; @@ -43,11 +43,12 @@ const I2C_BBPLL_OC_DIV_7_0: u32 = 3; const I2C_BBPLL_OC_DCUR: u32 = 5; pub(crate) fn esp32_rtc_bbpll_configure(xtal_freq: XtalClock, pll_freq: PllClock) { - let efuse = crate::peripherals::EFUSE::regs(); - let rtc_cntl = crate::peripherals::LPWR::regs(); - - let rtc_cntl_dbias_hp_volt: u32 = - RTC_CNTL_DBIAS_1V25 - efuse.blk0_rdata5().read().rd_vol_level_hp_inv().bits() as u32; + let rtc_cntl_dbias_hp_volt: u32 = RTC_CNTL_DBIAS_1V25 + - EFUSE::regs() + .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; @@ -59,7 +60,7 @@ pub(crate) fn esp32_rtc_bbpll_configure(xtal_freq: XtalClock, pll_freq: PllClock if matches!(pll_freq, PllClock::Pll320MHz) { // Raise the voltage, if needed - rtc_cntl + LPWR::regs() .reg() .modify(|_, w| unsafe { w.dig_dbias_wak().bits(DIG_DBIAS_80M_160M as u8) }); @@ -97,7 +98,7 @@ pub(crate) fn esp32_rtc_bbpll_configure(xtal_freq: XtalClock, pll_freq: PllClock regi2c_write!(I2C_BBPLL, I2C_BBPLL_BBADC_DSMP, BBPLL_BBADC_DSMP_VAL_320M); } else { // Raise the voltage - rtc_cntl + LPWR::regs() .reg() .modify(|_, w| unsafe { w.dig_dbias_wak().bits(dig_dbias_240_m as u8) }); @@ -145,15 +146,11 @@ pub(crate) fn esp32_rtc_bbpll_configure(xtal_freq: XtalClock, pll_freq: PllClock } pub(crate) fn esp32_rtc_bbpll_enable() { - crate::peripherals::LPWR::regs().options0().modify(|_, w| { - w.bias_i2c_force_pd() - .clear_bit() - .bb_i2c_force_pd() - .clear_bit() - .bbpll_force_pd() - .clear_bit() - .bbpll_i2c_force_pd() - .clear_bit() + LPWR::regs().options0().modify(|_, w| { + w.bias_i2c_force_pd().clear_bit(); + w.bb_i2c_force_pd().clear_bit(); + w.bbpll_force_pd().clear_bit(); + w.bbpll_i2c_force_pd().clear_bit() }); // reset BBPLL configuration @@ -169,80 +166,77 @@ pub(crate) fn esp32_rtc_bbpll_enable() { } pub(crate) fn esp32_rtc_update_to_xtal(freq: XtalClock, _div: u32) { - let apb_cntl = crate::peripherals::APB_CTRL::regs(); - let rtc_cntl = crate::peripherals::LPWR::regs(); + let value = ((freq.hz() >> 12) & UINT16_MAX) | (((freq.hz() >> 12) & UINT16_MAX) << 16); + esp32_update_cpu_freq(freq.hz()); - unsafe { - let value = (((freq.hz()) >> 12) & UINT16_MAX) | ((((freq.hz()) >> 12) & UINT16_MAX) << 16); - esp32_update_cpu_freq(freq.hz()); - - // set divider from XTAL to APB clock - apb_cntl.sysclk_conf().modify(|_, w| { - w.pre_div_cnt() - .bits(((freq.hz()) / REF_CLK_FREQ - 1) as u16) - }); - - // adjust ref_tick - apb_cntl.xtal_tick_conf().modify(|_, w| { - w.xtal_tick_num() - .bits(((freq.hz()) / REF_CLK_FREQ - 1) as u8) - }); - - // switch clock source - rtc_cntl.clk_conf().modify(|_, w| w.soc_clk_sel().xtal()); - rtc_cntl.store5().modify(|_, w| w.scratch5().bits(value)); - - // lower the voltage - rtc_cntl - .reg() - .modify(|_, w| w.dig_dbias_wak().bits(DIG_DBIAS_XTAL as u8)); - } -} + // set divider from XTAL to APB clock + APB_CTRL::regs().sysclk_conf().modify(|_, w| unsafe { + w.pre_div_cnt() + .bits(((freq.hz()) / REF_CLK_FREQ - 1) as u16) + }); -pub(crate) fn set_cpu_freq(cpu_freq_mhz: crate::clock::CpuClock) { - let efuse = crate::peripherals::EFUSE::regs(); - let dport = crate::peripherals::DPORT::regs(); - let rtc_cntl = crate::peripherals::LPWR::regs(); + // adjust ref_tick + APB_CTRL::regs().xtal_tick_conf().modify(|_, w| unsafe { + w.xtal_tick_num() + .bits(((freq.hz()) / REF_CLK_FREQ - 1) as u8) + }); - unsafe { - const RTC_CNTL_DBIAS_1V25: u32 = 7; + // switch clock source + LPWR::regs() + .clk_conf() + .modify(|_, w| w.soc_clk_sel().xtal()); + LPWR::regs() + .store5() + .modify(|_, w| unsafe { w.scratch5().bits(value) }); + + // lower the voltage + LPWR::regs() + .reg() + .modify(|_, w| unsafe { w.dig_dbias_wak().bits(DIG_DBIAS_XTAL as u8) }); +} - 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; +pub(crate) fn set_cpu_freq(cpu_freq_mhz: crate::clock::CpuClock) { + let rtc_cntl_dbias_hp_volt: u32 = RTC_CNTL_DBIAS_1V25 + - EFUSE::regs() + .blk0_rdata5() + .read() + .rd_vol_level_hp_inv() + .bits() as u32; + let dig_dbias_240_m: u32 = rtc_cntl_dbias_hp_volt; - const CPU_80M: u32 = 0; - const CPU_160M: u32 = 1; - const CPU_240M: u32 = 2; + const CPU_80M: u32 = 0; + const CPU_160M: u32 = 1; + const CPU_240M: u32 = 2; - let mut dbias = DIG_DBIAS_80M_160M; - let per_conf; + let mut dbias = DIG_DBIAS_80M_160M; + let per_conf; - match cpu_freq_mhz { - crate::clock::CpuClock::_160MHz => { - per_conf = CPU_160M; - } - crate::clock::CpuClock::_240MHz => { - dbias = dig_dbias_240_m; - per_conf = CPU_240M; - } - crate::clock::CpuClock::_80MHz => { - per_conf = CPU_80M; - } + match cpu_freq_mhz { + crate::clock::CpuClock::_160MHz => { + per_conf = CPU_160M; + } + crate::clock::CpuClock::_240MHz => { + dbias = dig_dbias_240_m; + per_conf = CPU_240M; + } + crate::clock::CpuClock::_80MHz => { + per_conf = CPU_80M; } - - let value = (((80 * MHZ) >> 12) & UINT16_MAX) | ((((80 * MHZ) >> 12) & UINT16_MAX) << 16); - dport - .cpu_per_conf() - .write(|w| w.cpuperiod_sel().bits(per_conf as u8)); - rtc_cntl - .reg() - .modify(|_, w| w.dig_dbias_wak().bits(dbias as u8)); - rtc_cntl.clk_conf().modify(|_, w| w.soc_clk_sel().pll()); - rtc_cntl.store5().modify(|_, w| w.scratch5().bits(value)); - - esp32_update_cpu_freq(cpu_freq_mhz.mhz()); } + + let value = (((80 * MHZ) >> 12) & UINT16_MAX) | ((((80 * MHZ) >> 12) & UINT16_MAX) << 16); + DPORT::regs() + .cpu_per_conf() + .write(|w| unsafe { w.cpuperiod_sel().bits(per_conf as u8) }); + LPWR::regs() + .reg() + .modify(|_, w| unsafe { w.dig_dbias_wak().bits(dbias as u8) }); + LPWR::regs().clk_conf().modify(|_, w| w.soc_clk_sel().pll()); + LPWR::regs() + .store5() + .modify(|_, w| unsafe { w.scratch5().bits(value) }); + + esp32_update_cpu_freq(cpu_freq_mhz.mhz()); } /// Pass the CPU clock in MHz so that ets_delay_us @@ -294,13 +288,12 @@ pub(super) fn enable_wifi(enable: bool) { } pub(super) fn reset_mac() { - const SYSTEM_MAC_RST: u8 = 1 << 2; DPORT::regs() - .core_rst_en() - .modify(|r, w| unsafe { w.core_rst().bits(r.core_rst().bits() | SYSTEM_MAC_RST) }); + .wifi_rst_en() + .modify(|_, w| w.mac_rst().set_bit()); DPORT::regs() - .core_rst_en() - .modify(|r, w| unsafe { w.core_rst().bits(r.core_rst().bits() & !SYSTEM_MAC_RST) }); + .wifi_rst_en() + .modify(|_, w| w.mac_rst().clear_bit()); } pub(super) fn init_clocks() { diff --git a/esp-hal/src/clock/clocks_ll/esp32c2.rs b/esp-hal/src/clock/clocks_ll/esp32c2.rs index bea0919c98..3db8f9afb5 100644 --- a/esp-hal/src/clock/clocks_ll/esp32c2.rs +++ b/esp-hal/src/clock/clocks_ll/esp32c2.rs @@ -1,6 +1,6 @@ use crate::{ clock::{ApbClock, Clock, CpuClock, PllClock, XtalClock}, - peripherals::{APB_CTRL, MODEM_CLKRST}, + peripherals::{APB_CTRL, LPWR, MODEM_CLKRST, SYSTEM}, rom::{regi2c_write, regi2c_write_mask}, }; @@ -36,8 +36,6 @@ const I2C_MST_BBPLL_STOP_FORCE_HIGH: u32 = 1 << 2; const I2C_MST_BBPLL_STOP_FORCE_LOW: u32 = 1 << 3; pub(crate) fn esp32c2_rtc_bbpll_configure(xtal_freq: XtalClock, _pll_freq: PllClock) { - let system = crate::peripherals::SYSTEM::regs(); - let div_ref: u32; let div7_0: u32; let dr1: u32; @@ -59,7 +57,7 @@ pub(crate) fn esp32c2_rtc_bbpll_configure(xtal_freq: XtalClock, _pll_freq: PllCl } // Set this register to let the digital part know 480M PLL is used - system + SYSTEM::regs() .cpu_per_conf() .modify(|_, w| w.pll_freq_sel().set_bit()); @@ -106,66 +104,51 @@ pub(crate) fn esp32c2_rtc_bbpll_configure(xtal_freq: XtalClock, _pll_freq: PllCl } pub(crate) fn esp32c2_rtc_bbpll_enable() { - let rtc_cntl = crate::peripherals::LPWR::regs(); - - rtc_cntl.options0().modify(|_, w| { - w.bb_i2c_force_pd() - .clear_bit() - .bbpll_force_pd() - .clear_bit() - .bbpll_i2c_force_pd() - .clear_bit() + LPWR::regs().options0().modify(|_, w| { + w.bb_i2c_force_pd().clear_bit(); + w.bbpll_force_pd().clear_bit(); + w.bbpll_i2c_force_pd().clear_bit() }); } -pub(crate) fn esp32c2_rtc_update_to_xtal(freq: XtalClock, _div: u32) { +pub(crate) fn esp32c2_rtc_update_to_xtal(freq: XtalClock, div: u32) { crate::rom::ets_update_cpu_frequency_rom(freq.mhz()); - let system_control = crate::peripherals::SYSTEM::regs(); - unsafe { - // Set divider from XTAL to APB clock. Need to set divider to 1 (reg. value 0) - // first. - system_control.sysclk_conf().modify(|_, w| { - w.pre_div_cnt() - .bits(0) - .pre_div_cnt() - .bits((_div - 1) as u16) - }); - - // No need to adjust the REF_TICK - - // Switch clock source - system_control - .sysclk_conf() - .modify(|_, w| w.soc_clk_sel().bits(0)); - } + // Set divider from XTAL to APB clock. Need to set divider to 1 (reg. value 0) + // first. + SYSTEM::regs().sysclk_conf().modify(|_, w| unsafe { + w.pre_div_cnt().bits(0); + w.pre_div_cnt().bits((div - 1) as u16) + }); + + // No need to adjust the REF_TICK + + // Switch clock source + SYSTEM::regs() + .sysclk_conf() + .modify(|_, w| unsafe { w.soc_clk_sel().bits(0) }); } pub(crate) fn esp32c2_rtc_freq_to_pll_mhz(cpu_clock_speed: CpuClock) { - let system_control = crate::peripherals::SYSTEM::regs(); - - unsafe { - system_control - .sysclk_conf() - .modify(|_, w| w.pre_div_cnt().bits(0).soc_clk_sel().bits(1)); - system_control.cpu_per_conf().modify(|_, w| { - w.cpuperiod_sel().bits(match cpu_clock_speed { - CpuClock::_80MHz => 0, - CpuClock::_120MHz => 1, - }) - }); - } + SYSTEM::regs().sysclk_conf().modify(|_, w| unsafe { + w.pre_div_cnt().bits(0); + w.soc_clk_sel().bits(1) + }); + SYSTEM::regs().cpu_per_conf().modify(|_, w| unsafe { + w.cpuperiod_sel().bits(match cpu_clock_speed { + CpuClock::_80MHz => 0, + CpuClock::_120MHz => 1, + }) + }); crate::rom::ets_update_cpu_frequency_rom(cpu_clock_speed.mhz()); } pub(crate) fn esp32c2_rtc_apb_freq_update(apb_freq: ApbClock) { - let rtc_cntl = crate::peripherals::LPWR::regs(); - let value = ((apb_freq.hz() >> 12) & u16::MAX as u32) | (((apb_freq.hz() >> 12) & u16::MAX as u32) << 16); - rtc_cntl + LPWR::regs() .store5() .modify(|_, w| unsafe { w.scratch5().bits(value) }); } @@ -199,13 +182,12 @@ pub(super) fn enable_wifi(_: bool) { } pub(super) fn reset_mac() { - const SYSTEM_MAC_RST: u32 = 1 << 2; APB_CTRL::regs() .wifi_rst_en() - .modify(|r, w| unsafe { w.wifi_rst().bits(r.wifi_rst().bits() | SYSTEM_MAC_RST) }); + .modify(|_, w| w.mac_rst().set_bit()); APB_CTRL::regs() .wifi_rst_en() - .modify(|r, w| unsafe { w.wifi_rst().bits(r.wifi_rst().bits() & !SYSTEM_MAC_RST) }); + .modify(|_, w| w.mac_rst().clear_bit()); } pub(super) fn init_clocks() { @@ -220,39 +202,30 @@ pub(super) fn init_clocks() { } pub(super) fn ble_rtc_clk_init() { - let modem_clkrst = MODEM_CLKRST::regs(); - modem_clkrst - .modem_lp_timer_conf() - .modify(|_, w| w.lp_timer_sel_xtal32k().clear_bit()); - modem_clkrst - .modem_lp_timer_conf() - .modify(|_, w| w.lp_timer_sel_xtal().set_bit()); - modem_clkrst - .modem_lp_timer_conf() - .modify(|_, w| w.lp_timer_sel_8m().clear_bit()); - modem_clkrst - .modem_lp_timer_conf() - .modify(|_, w| w.lp_timer_sel_rtc_slow().clear_bit()); + let modem_clkrst = M; + MODEM_CLKRST::regs().modem_lp_timer_conf().modify(|_, w| { + w.lp_timer_sel_xtal32k().clear_bit(); + w.lp_timer_sel_xtal().set_bit(); + w.lp_timer_sel_8m().clear_bit(); + w.lp_timer_sel_rtc_slow().clear_bit() + }); // assume 40MHz xtal - modem_clkrst + MODEM_CLKRST::regs() .modem_lp_timer_conf() .modify(|_, w| unsafe { w.lp_timer_clk_div_num().bits(249) }); - modem_clkrst - .etm_clk_conf() - .modify(|_, w| w.etm_clk_active().set_bit()); - modem_clkrst - .etm_clk_conf() - .modify(|_, w| w.etm_clk_sel().clear_bit()); + MODEM_CLKRST::regs().etm_clk_conf().modify(|_, w| { + w.etm_clk_active().set_bit(); + w.etm_clk_sel().clear_bit() + }); } pub(super) fn reset_rpa() { - const BLE_RPA_REST_BIT: u32 = 1 << 27; APB_CTRL::regs() .wifi_rst_en() - .modify(|r, w| unsafe { w.bits(r.bits() | BLE_RPA_REST_BIT) }); + .modify(|_, w| w.ble_rpa_rst().set_bit()); APB_CTRL::regs() .wifi_rst_en() - .modify(|r, w| unsafe { w.bits(r.bits() & !BLE_RPA_REST_BIT) }); + .modify(|_, w| w.ble_rpa_rst().clear_bit()); } diff --git a/esp-hal/src/clock/clocks_ll/esp32c3.rs b/esp-hal/src/clock/clocks_ll/esp32c3.rs index 57d5a6e5dd..1b491789c9 100644 --- a/esp-hal/src/clock/clocks_ll/esp32c3.rs +++ b/esp-hal/src/clock/clocks_ll/esp32c3.rs @@ -1,6 +1,6 @@ use crate::{ clock::{ApbClock, Clock, CpuClock, PllClock, XtalClock}, - peripherals::{APB_CTRL, LPWR}, + peripherals::{APB_CTRL, LPWR, SYSTEM}, rom::{regi2c_write, regi2c_write_mask}, }; @@ -40,8 +40,6 @@ const I2C_MST_BBPLL_STOP_FORCE_HIGH: u32 = 1 << 3; const I2C_MST_BBPLL_STOP_FORCE_LOW: u32 = 1 << 2; pub(crate) fn esp32c3_rtc_bbpll_configure(xtal_freq: XtalClock, pll_freq: PllClock) { - let system = crate::peripherals::SYSTEM::regs(); - let div_ref: u32; let div7_0: u32; let dr1: u32; @@ -62,12 +60,13 @@ pub(crate) fn esp32c3_rtc_bbpll_configure(xtal_freq: XtalClock, pll_freq: PllClo set_reg_mask(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_LOW); } - if matches!(pll_freq, PllClock::Pll480MHz) { - // Set this register to let the digital part know 480M PLL is used - system - .cpu_per_conf() - .modify(|_, w| w.pll_freq_sel().set_bit()); + // Set this register to let the digital part know 480M PLL is used + SYSTEM::regs().cpu_per_conf().modify(|_, w| { + w.pll_freq_sel() + .bit(matches!(pll_freq, PllClock::Pll480MHz)) + }); + if matches!(pll_freq, PllClock::Pll480MHz) { // Configure 480M PLL match xtal_freq { XtalClock::_40M => { @@ -103,11 +102,6 @@ pub(crate) fn esp32c3_rtc_bbpll_configure(xtal_freq: XtalClock, pll_freq: PllClo regi2c_write!(I2C_BBPLL, I2C_BBPLL_MODE_HF, 0x6b); } else { - // Clear this register to let the digital part know 320M PLL is used - system - .cpu_per_conf() - .modify(|_, w| w.pll_freq_sel().clear_bit()); - // Configure 320M PLL match xtal_freq { XtalClock::_40M => { @@ -167,65 +161,51 @@ pub(crate) fn esp32c3_rtc_bbpll_configure(xtal_freq: XtalClock, pll_freq: PllClo } pub(crate) fn esp32c3_rtc_bbpll_enable() { - let rtc_cntl = crate::peripherals::LPWR::regs(); - - rtc_cntl.options0().modify(|_, w| { - w.bb_i2c_force_pd() - .clear_bit() - .bbpll_force_pd() - .clear_bit() - .bbpll_i2c_force_pd() - .clear_bit() + LPWR::regs().options0().modify(|_, w| { + w.bb_i2c_force_pd().clear_bit(); + w.bbpll_force_pd().clear_bit(); + w.bbpll_i2c_force_pd().clear_bit() }); } pub(crate) fn esp32c3_rtc_update_to_xtal(freq: XtalClock, _div: u32) { crate::rom::ets_update_cpu_frequency_rom(freq.mhz()); - let system_control = crate::peripherals::SYSTEM::regs(); - unsafe { - // Set divider from XTAL to APB clock. Need to set divider to 1 (reg. value 0) - // first. - system_control.sysclk_conf().modify(|_, w| { - w.pre_div_cnt() - .bits(0) - .pre_div_cnt() - .bits((_div - 1) as u16) - }); - - // No need to adjust the REF_TICK - - // Switch clock source - system_control - .sysclk_conf() - .modify(|_, w| w.soc_clk_sel().bits(0)); - } + // Set divider from XTAL to APB clock. Need to set divider to 1 (reg. value 0) + // first. + SYSTEM::regs().sysclk_conf().modify(|_, w| unsafe { + w.pre_div_cnt().bits(0); + w.pre_div_cnt().bits((_div - 1) as u16) + }); + + // No need to adjust the REF_TICK + + // Switch clock source + SYSTEM::regs() + .sysclk_conf() + .modify(|_, w| unsafe { w.soc_clk_sel().bits(0) }); } pub(crate) fn esp32c3_rtc_freq_to_pll_mhz(cpu_clock_speed: CpuClock) { - let system_control = crate::peripherals::SYSTEM::regs(); - - unsafe { - system_control - .sysclk_conf() - .modify(|_, w| w.pre_div_cnt().bits(0).soc_clk_sel().bits(1)); - system_control.cpu_per_conf().modify(|_, w| { - w.cpuperiod_sel().bits(match cpu_clock_speed { - CpuClock::_80MHz => 0, - CpuClock::_160MHz => 1, - }) - }); - } + SYSTEM::regs().sysclk_conf().modify(|_, w| unsafe { + w.pre_div_cnt().bits(0); + w.soc_clk_sel().bits(1) + }); + SYSTEM::regs().cpu_per_conf().modify(|_, w| unsafe { + w.cpuperiod_sel().bits(match cpu_clock_speed { + CpuClock::_80MHz => 0, + CpuClock::_160MHz => 1, + }) + }); crate::rom::ets_update_cpu_frequency_rom(cpu_clock_speed.mhz()); } pub(crate) fn esp32c3_rtc_apb_freq_update(apb_freq: ApbClock) { - let rtc_cntl = crate::peripherals::LPWR::regs(); let value = ((apb_freq.hz() >> 12) & u16::MAX as u32) | (((apb_freq.hz() >> 12) & u16::MAX as u32) << 16); - rtc_cntl + LPWR::regs() .store5() .modify(|_, w| unsafe { w.scratch5().bits(value) }); } @@ -259,24 +239,25 @@ pub(super) fn enable_bt(_: bool) { } pub(super) fn reset_mac() { - const SYSTEM_MAC_RST: u32 = 1 << 2; APB_CTRL::regs() .wifi_rst_en() - .modify(|r, w| unsafe { w.wifi_rst().bits(r.wifi_rst().bits() | SYSTEM_MAC_RST) }); + .modify(|_, w| w.mac_rst().set_bit()); APB_CTRL::regs() .wifi_rst_en() - .modify(|r, w| unsafe { w.wifi_rst().bits(r.wifi_rst().bits() & !SYSTEM_MAC_RST) }); + .modify(|_, w| w.mac_rst().clear_bit()); } pub(super) fn init_clocks() { // undo the power down in base_settings (esp32c3_sleep) - LPWR::regs() - .dig_iso() - .modify(|_, w| w.wifi_force_iso().clear_bit().bt_force_iso().clear_bit()); + LPWR::regs().dig_iso().modify(|_, w| { + w.wifi_force_iso().clear_bit(); + w.bt_force_iso().clear_bit() + }); - LPWR::regs() - .dig_pwc() - .modify(|_, w| w.wifi_force_pd().clear_bit().bt_force_pd().clear_bit()); + LPWR::regs().dig_pwc().modify(|_, w| { + w.wifi_force_pd().clear_bit(); + w.bt_force_pd().clear_bit() + }); // from `esp_perip_clk_init` const SYSTEM_WIFI_CLK_I2C_CLK_EN: u32 = 1 << 5; diff --git a/esp-hal/src/clock/clocks_ll/esp32c6.rs b/esp-hal/src/clock/clocks_ll/esp32c6.rs index 503b31804c..fb5d1d95a2 100644 --- a/esp-hal/src/clock/clocks_ll/esp32c6.rs +++ b/esp-hal/src/clock/clocks_ll/esp32c6.rs @@ -1,6 +1,6 @@ use crate::{ clock::{ApbClock, Clock, CpuClock, PllClock, XtalClock}, - peripherals::{MODEM_LPCON, MODEM_SYSCON, PMU}, + peripherals::{I2C_ANA_MST, LP_AON, MODEM_LPCON, MODEM_SYSCON, PCR, PMU}, rtc_cntl::rtc::CpuClockSource, }; @@ -30,20 +30,6 @@ const I2C_BBPLL_OC_VCO_DBIAS: u8 = 9; const I2C_BBPLL_OC_VCO_DBIAS_MSB: u8 = 1; const I2C_BBPLL_OC_VCO_DBIAS_LSB: u8 = 0; -// Analog function control register -const I2C_MST_ANA_CONF0_REG: u32 = 0x600AF818; -const I2C_MST_BBPLL_STOP_FORCE_HIGH: u32 = 1 << 2; -const I2C_MST_BBPLL_STOP_FORCE_LOW: u32 = 1 << 3; -const I2C_MST_BBPLL_CAL_DONE: u32 = 1 << 24; - -unsafe fn modem_lpcon<'a>() -> &'a esp32c6::modem_lpcon::RegisterBlock { - &*esp32c6::MODEM_LPCON::ptr() -} - -unsafe fn pcr<'a>() -> &'a esp32c6::pcr::RegisterBlock { - &*esp32c6::PCR::ptr() -} - // rtc_clk_bbpll_configure pub(crate) fn esp32c6_rtc_bbpll_configure(xtal_freq: XtalClock, pll_freq: PllClock) { esp32c6_rtc_bbpll_configure_raw(xtal_freq.mhz(), pll_freq.mhz()) @@ -55,33 +41,30 @@ pub(crate) fn esp32c6_rtc_bbpll_configure_raw(_xtal_freq: u32, pll_freq: u32) { // Do nothing debug_assert!(pll_freq == 480); - critical_section::with(|_| unsafe { + critical_section::with(|_| { // enable i2c mst clk by force on (temporarily) - let was_i2c_mst_en = modem_lpcon().clk_conf().read().clk_i2c_mst_en().bit(); - modem_lpcon() + let was_i2c_mst_en = MODEM_LPCON::regs().clk_conf().read().clk_i2c_mst_en().bit(); + MODEM_LPCON::regs() .clk_conf() .modify(|_, w| w.clk_i2c_mst_en().set_bit()); - modem_lpcon() + MODEM_LPCON::regs() .i2c_mst_clk_conf() .modify(|_, w| w.clk_i2c_mst_sel_160m().set_bit()); - let i2c_mst_ana_conf0_reg_ptr = I2C_MST_ANA_CONF0_REG as *mut u32; // BBPLL CALIBRATION START - i2c_mst_ana_conf0_reg_ptr.write_volatile( - i2c_mst_ana_conf0_reg_ptr.read_volatile() & !I2C_MST_BBPLL_STOP_FORCE_HIGH, - ); - i2c_mst_ana_conf0_reg_ptr.write_volatile( - i2c_mst_ana_conf0_reg_ptr.read_volatile() | I2C_MST_BBPLL_STOP_FORCE_LOW, - ); + I2C_ANA_MST::regs().ana_conf0().modify(|_, w| { + w.bbpll_stop_force_high().clear_bit(); + w.bbpll_stop_force_low().set_bit() + }); - let div_ref = 0u32; - let div7_0 = 8u32; - let dr1 = 0u32; - let dr3 = 0u32; - let dchgp = 5u32; - let dcur = 3u32; - let dbias = 2u32; + let div_ref = 0; + let div7_0 = 8; + let dr1 = 0; + let dr3 = 0; + let dchgp = 5; + let dcur = 3; + let dbias = 2; let i2c_bbpll_lref = (dchgp << I2C_BBPLL_OC_DCHGP_LSB) | div_ref; let i2c_bbpll_div_7_0 = div7_0; @@ -92,13 +75,13 @@ pub(crate) fn esp32c6_rtc_bbpll_configure_raw(_xtal_freq: u32, pll_freq: u32) { I2C_BBPLL, I2C_BBPLL_HOSTID, I2C_BBPLL_OC_REF_DIV, - i2c_bbpll_lref as u8, + i2c_bbpll_lref, ); regi2c_write( I2C_BBPLL, I2C_BBPLL_HOSTID, I2C_BBPLL_OC_DIV_7_0, - i2c_bbpll_div_7_0 as u8, + i2c_bbpll_div_7_0, ); regi2c_write_mask( I2C_BBPLL, @@ -106,7 +89,7 @@ pub(crate) fn esp32c6_rtc_bbpll_configure_raw(_xtal_freq: u32, pll_freq: u32) { I2C_BBPLL_OC_DR1, I2C_BBPLL_OC_DR1_MSB, I2C_BBPLL_OC_DR1_LSB, - dr1 as u8, + dr1, ); regi2c_write_mask( I2C_BBPLL, @@ -114,13 +97,13 @@ pub(crate) fn esp32c6_rtc_bbpll_configure_raw(_xtal_freq: u32, pll_freq: u32) { I2C_BBPLL_OC_DR3, I2C_BBPLL_OC_DR3_MSB, I2C_BBPLL_OC_DR3_LSB, - dr3 as u8, + dr3, ); regi2c_write( I2C_BBPLL, I2C_BBPLL_HOSTID, I2C_BBPLL_OC_DCUR, - i2c_bbpll_dcur as u8, + i2c_bbpll_dcur, ); regi2c_write_mask( I2C_BBPLL, @@ -128,42 +111,41 @@ pub(crate) fn esp32c6_rtc_bbpll_configure_raw(_xtal_freq: u32, pll_freq: u32) { I2C_BBPLL_OC_VCO_DBIAS, I2C_BBPLL_OC_VCO_DBIAS_MSB, I2C_BBPLL_OC_VCO_DBIAS_LSB, - dbias as u8, + dbias, ); // WAIT CALIBRATION DONE - while (i2c_mst_ana_conf0_reg_ptr.read_volatile() & I2C_MST_BBPLL_CAL_DONE) == 0 {} + while I2C_ANA_MST::regs() + .ana_conf0() + .read() + .cal_done() + .bit_is_clear() + {} // workaround bbpll calibration might stop early crate::rom::ets_delay_us(10); // BBPLL CALIBRATION STOP - i2c_mst_ana_conf0_reg_ptr.write_volatile( - i2c_mst_ana_conf0_reg_ptr.read_volatile() & !I2C_MST_BBPLL_STOP_FORCE_LOW, - ); - i2c_mst_ana_conf0_reg_ptr.write_volatile( - i2c_mst_ana_conf0_reg_ptr.read_volatile() | I2C_MST_BBPLL_STOP_FORCE_HIGH, - ); + I2C_ANA_MST::regs().ana_conf0().modify(|_, w| { + w.bbpll_stop_force_high().set_bit(); + w.bbpll_stop_force_low().clear_bit() + }); - modem_lpcon() + MODEM_LPCON::regs() .clk_conf() .modify(|_, w| w.clk_i2c_mst_en().bit(was_i2c_mst_en)); }); } pub(crate) fn esp32c6_rtc_bbpll_enable() { - let pmu = crate::peripherals::PMU::regs(); - - pmu.imm_hp_ck_power().modify(|_, w| { - w.tie_high_xpd_bb_i2c() - .set_bit() - .tie_high_xpd_bbpll() - .set_bit() - .tie_high_xpd_bbpll_i2c() - .set_bit() + PMU::regs().imm_hp_ck_power().modify(|_, w| { + w.tie_high_xpd_bb_i2c().set_bit(); + w.tie_high_xpd_bbpll().set_bit(); + w.tie_high_xpd_bbpll_i2c().set_bit() }); - pmu.imm_hp_ck_power() + PMU::regs() + .imm_hp_ck_power() .modify(|_, w| w.tie_high_global_bbpll_icg().set_bit()); } @@ -200,30 +182,26 @@ pub(crate) fn esp32c6_rtc_freq_to_pll_mhz_raw(cpu_clock_speed_mhz: u32) { // 80MHz after the switch. PLL = 480MHz, so divider is 6. clk_ll_mspi_fast_set_hs_divider(6); - let pcr = crate::peripherals::PCR::regs(); - unsafe { - pcr.cpu_freq_conf().modify(|_, w| { - w.cpu_hs_div_num() - .bits(((480 / cpu_clock_speed_mhz / 3) - 1) as u8) - .cpu_hs_120m_force() - .clear_bit() - }); + PCR::regs().cpu_freq_conf().modify(|_, w| unsafe { + w.cpu_hs_div_num() + .bits(((480 / cpu_clock_speed_mhz / 3) - 1) as u8); + w.cpu_hs_120m_force().clear_bit() + }); - pcr.cpu_freq_conf() - .modify(|_, w| w.cpu_hs_120m_force().clear_bit()); + PCR::regs() + .cpu_freq_conf() + .modify(|_, w| w.cpu_hs_120m_force().clear_bit()); - CpuClockSource::Pll.select(); - } + CpuClockSource::Pll.select(); crate::rom::ets_update_cpu_frequency_rom(cpu_clock_speed_mhz); } pub(crate) fn esp32c6_rtc_apb_freq_update(apb_freq: ApbClock) { - let lp_aon = crate::peripherals::LP_AON::regs(); let value = ((apb_freq.hz() >> 12) & u16::MAX as u32) | (((apb_freq.hz() >> 12) & u16::MAX as u32) << 16); - lp_aon + LP_AON::regs() .store5() .modify(|_, w| unsafe { w.lp_aon_store5().bits(value) }); } @@ -231,214 +209,133 @@ pub(crate) fn esp32c6_rtc_apb_freq_update(apb_freq: ApbClock) { fn clk_ll_mspi_fast_set_hs_divider(divider: u32) { // SOC_ROOT_CLK ------> MSPI_FAST_CLK // HS divider option: 4, 5, 6 (PCR_MSPI_FAST_HS_DIV_NUM=3, 4, 5) - let pcr = crate::peripherals::PCR::regs(); - unsafe { - match divider { - 4 => pcr - .mspi_clk_conf() - .modify(|_, w| w.mspi_fast_hs_div_num().bits(3)), - 5 => pcr - .mspi_clk_conf() - .modify(|_, w| w.mspi_fast_hs_div_num().bits(4)), - 6 => pcr - .mspi_clk_conf() - .modify(|_, w| w.mspi_fast_hs_div_num().bits(5)), - _ => panic!("Unsupported HS MSPI_FAST divider"), - }; - } + let div_num = match divider { + 4..=6 => divider as u8 - 1, + _ => panic!("Unsupported HS MSPI_FAST divider"), + }; + + PCR::regs() + .mspi_clk_conf() + .modify(|_, w| unsafe { w.mspi_fast_hs_div_num().bits(div_num) }); } +const REGI2C_BBPLL: u8 = 0x66; const REGI2C_BIAS: u8 = 0x6a; const REGI2C_DIG_REG: u8 = 0x6d; const REGI2C_ULP_CAL: u8 = 0x61; const REGI2C_SAR_I2C: u8 = 0x69; -const REGI2C_RTC_SLAVE_ID_V: u8 = 0xFF; -const REGI2C_RTC_SLAVE_ID_S: u8 = 0; -const REGI2C_RTC_ADDR_V: u8 = 0xFF; -const REGI2C_RTC_ADDR_S: u8 = 8; -const REGI2C_RTC_WR_CNTL_S: u8 = 24; -const REGI2C_RTC_DATA_V: u8 = 0xFF; -const REGI2C_RTC_DATA_S: u8 = 16; - -const REGI2C_BBPLL: u8 = 0x66; - -const REGI2C_BBPLL_DEVICE_EN: u16 = 1 << 5; -const REGI2C_BIAS_DEVICE_EN: u16 = 1 << 4; -const REGI2C_DIG_REG_DEVICE_EN: u16 = 1 << 8; -const REGI2C_ULP_CAL_DEVICE_EN: u16 = 1 << 6; -const REGI2C_SAR_I2C_DEVICE_EN: u16 = 1 << 7; - -fn regi2c_enable_block(block: u8) { - let modem_lpcon = crate::peripherals::MODEM_LPCON::regs(); - let lp_i2c_ana = crate::peripherals::LP_I2C_ANA_MST::regs(); +const I2C_MST_ANA_CONF1_M: u32 = 0x00FFFFFF; - modem_lpcon +fn regi2c_enable_block(block: u8) -> usize { + MODEM_LPCON::regs() .clk_conf() .modify(|_, w| w.clk_i2c_mst_en().set_bit()); - modem_lpcon - .i2c_mst_clk_conf() - .modify(|_, w| w.clk_i2c_mst_sel_160m().set_bit()); - - lp_i2c_ana - .date() - .modify(|_, w| w.lp_i2c_ana_mast_i2c_mat_clk_en().set_bit()); - // Before config I2C register, enable corresponding slave. - let en_bit = match block { - v if v == REGI2C_BBPLL => REGI2C_BBPLL_DEVICE_EN, - v if v == REGI2C_BIAS => REGI2C_BIAS_DEVICE_EN, - v if v == REGI2C_DIG_REG => REGI2C_DIG_REG_DEVICE_EN, - v if v == REGI2C_ULP_CAL => REGI2C_ULP_CAL_DEVICE_EN, - v if v == REGI2C_SAR_I2C => REGI2C_SAR_I2C_DEVICE_EN, - _ => return, - }; - - unsafe { - lp_i2c_ana.device_en().modify(|r, w| { - w.lp_i2c_ana_mast_i2c_device_en() - .bits(r.lp_i2c_ana_mast_i2c_device_en().bits() | en_bit) - }); - } -} - -fn regi2c_disable_block(block: u8) { - let en_bit = match block { - v if v == REGI2C_BBPLL => REGI2C_BBPLL_DEVICE_EN, - v if v == REGI2C_BIAS => REGI2C_BIAS_DEVICE_EN, - v if v == REGI2C_DIG_REG => REGI2C_DIG_REG_DEVICE_EN, - v if v == REGI2C_ULP_CAL => REGI2C_ULP_CAL_DEVICE_EN, - v if v == REGI2C_SAR_I2C => REGI2C_SAR_I2C_DEVICE_EN, - _ => return, + let i2c_sel_bits = I2C_ANA_MST::regs().ana_conf2().read(); + let i2c_sel = match block { + v if v == REGI2C_BBPLL => i2c_sel_bits.bbpll_mst_sel().bit_is_set(), + v if v == REGI2C_BIAS => i2c_sel_bits.bias_mst_sel().bit_is_set(), + v if v == REGI2C_DIG_REG => i2c_sel_bits.dig_reg_mst_sel().bit_is_set(), + v if v == REGI2C_ULP_CAL => i2c_sel_bits.ulp_cal_mst_sel().bit_is_set(), + v if v == REGI2C_SAR_I2C => i2c_sel_bits.sar_i2c_mst_sel().bit_is_set(), + _ => unreachable!(), }; + I2C_ANA_MST::regs().ana_conf1().write(|w| unsafe { + w.bits(I2C_MST_ANA_CONF1_M); + match block { + v if v == REGI2C_BBPLL => w.bbpll_rd().clear_bit(), + v if v == REGI2C_BIAS => w.bias_rd().clear_bit(), + v if v == REGI2C_DIG_REG => w.dig_reg_rd().clear_bit(), + v if v == REGI2C_ULP_CAL => w.ulp_cal_rd().clear_bit(), + v if v == REGI2C_SAR_I2C => w.sar_i2c_rd().clear_bit(), + _ => unreachable!(), + } + }); - unsafe { - let lp_i2c_ana = crate::peripherals::LP_I2C_ANA_MST::regs(); - lp_i2c_ana.device_en().modify(|r, w| { - w.lp_i2c_ana_mast_i2c_device_en() - .bits(r.lp_i2c_ana_mast_i2c_device_en().bits() & !en_bit) - }); + if i2c_sel { + 0 + } else { + 1 } } pub(crate) fn regi2c_write(block: u8, _host_id: u8, reg_add: u8, data: u8) { - regi2c_enable_block(block); - let lp_i2c_ana = crate::peripherals::LP_I2C_ANA_MST::regs(); - - let block_shifted = (block as u32 & REGI2C_RTC_SLAVE_ID_V as u32) << REGI2C_RTC_SLAVE_ID_S; - let reg_add_shifted = (reg_add as u32 & REGI2C_RTC_ADDR_V as u32) << REGI2C_RTC_ADDR_S; - let write_bit = 1u32 << REGI2C_RTC_WR_CNTL_S; - - let new_value = (data as u32) << REGI2C_RTC_DATA_S; + let master = regi2c_enable_block(block); - lp_i2c_ana - .i2c0_ctrl() - .write(|w| unsafe { w.bits(block_shifted | reg_add_shifted | write_bit | new_value) }); - - while lp_i2c_ana - .i2c0_ctrl() - .read() - .lp_i2c_ana_mast_i2c0_busy() - .bit() - {} + I2C_ANA_MST::regs().i2c_ctrl(master).write(|w| unsafe { + w.slave_addr().bits(block); + w.slave_reg_addr().bits(reg_add); + w.read_write().set_bit(); + w.data().bits(data) + }); - regi2c_disable_block(block); + while I2C_ANA_MST::regs().i2c_ctrl(master).read().busy().bit() {} } pub(crate) fn regi2c_write_mask(block: u8, _host_id: u8, reg_add: u8, msb: u8, lsb: u8, data: u8) { assert!(msb < 8 + lsb); - let lp_i2c_ana = crate::peripherals::LP_I2C_ANA_MST::regs(); - regi2c_enable_block(block); - - let block_shifted = (block as u32 & REGI2C_RTC_SLAVE_ID_V as u32) << REGI2C_RTC_SLAVE_ID_S; - let reg_add_shifted = (reg_add as u32 & REGI2C_RTC_ADDR_V as u32) << REGI2C_RTC_ADDR_S; - let write_bit = 1u32 << REGI2C_RTC_WR_CNTL_S; - - unsafe { - // Read the i2c bus register - lp_i2c_ana.i2c0_ctrl().write(|w| { - w.lp_i2c_ana_mast_i2c0_ctrl() - .bits(block_shifted | reg_add_shifted) - }); - - while lp_i2c_ana - .i2c0_ctrl() - .read() - .lp_i2c_ana_mast_i2c0_busy() - .bit() - {} - - let mut temp = lp_i2c_ana - .i2c0_data() - .read() - .lp_i2c_ana_mast_i2c0_rdata() - .bits() as u32; + let master = regi2c_enable_block(block); - // Mask the value field - temp &= (!(0xFFFFFFFF << lsb)) | (0xFFFFFFFF << (msb + 1)); - - // Write the value into the temporary - temp |= (data as u32 & (!(0xFFFFFFFF << (msb - lsb + 1)))) << lsb; - - // Write the i2c bus register - let new_value = (temp & REGI2C_RTC_DATA_V as u32) << REGI2C_RTC_DATA_S; - - lp_i2c_ana.i2c0_ctrl().write(|w| { - w.lp_i2c_ana_mast_i2c0_ctrl() - .bits(block_shifted | reg_add_shifted | write_bit | new_value) - }); + // Read the i2c bus register + I2C_ANA_MST::regs().i2c_ctrl(master).write(|w| unsafe { + w.slave_addr().bits(block); + w.slave_reg_addr().bits(reg_add) + }); - while lp_i2c_ana - .i2c0_ctrl() - .read() - .lp_i2c_ana_mast_i2c0_busy() - .bit() - {} + while I2C_ANA_MST::regs().i2c_ctrl(master).read().busy().bit() {} + + // Example: LSB=2, MSB = 5 + // unwritten_bits = 1100 0011 + // data_mask = 0000 1111 + // data_bits = 00xx xx00 + let unwritten_bits = !(u8::MAX << lsb) | (u8::MAX << (msb + 1)); + let data_mask = !(u8::MAX << (msb - lsb + 1)); + let data_bits = (data & data_mask) << lsb; + + I2C_ANA_MST::regs().i2c_ctrl(master).modify(|r, w| unsafe { + w.slave_addr().bits(block); + w.slave_reg_addr().bits(reg_add); + w.read_write().set_bit(); + w.data() + .bits((r.data().bits() & unwritten_bits) | data_bits) + }); - regi2c_disable_block(block); - } + while I2C_ANA_MST::regs().i2c_ctrl(master).read().busy().bit() {} } // clk_ll_ahb_set_ls_divider fn esp32c6_ahb_set_ls_divider(div: u8) { - unsafe { - pcr() - .ahb_freq_conf() - .modify(|_, w| w.ahb_ls_div_num().bits(div - 1)); - } + PCR::regs() + .ahb_freq_conf() + .modify(|_, w| unsafe { w.ahb_ls_div_num().bits(div - 1) }); } // clk_ll_cpu_set_ls_divider fn esp32c6_cpu_set_ls_divider(div: u8) { - unsafe { - pcr() - .cpu_freq_conf() - .modify(|_, w| w.cpu_ls_div_num().bits(div - 1)); - } + PCR::regs() + .cpu_freq_conf() + .modify(|_, w| unsafe { w.cpu_ls_div_num().bits(div - 1) }); } // clk_ll_cpu_get_ls_divider pub(crate) fn esp32c6_cpu_get_ls_divider() -> u8 { - unsafe { - let cpu_ls_div = pcr().cpu_freq_conf().read().cpu_ls_div_num().bits(); - let hp_root_ls_div = pcr().sysclk_conf().read().ls_div_num().bits(); - (hp_root_ls_div + 1) * (cpu_ls_div + 1) - } + let cpu_ls_div = PCR::regs().cpu_freq_conf().read().cpu_ls_div_num().bits(); + let hp_root_ls_div = PCR::regs().sysclk_conf().read().ls_div_num().bits(); + (hp_root_ls_div + 1) * (cpu_ls_div + 1) } // clk_ll_cpu_get_hs_divider pub(crate) fn esp32c6_cpu_get_hs_divider() -> u8 { - unsafe { - let force_120m = pcr().cpu_freq_conf().read().cpu_hs_120m_force().bit(); - let cpu_hs_div = pcr().cpu_freq_conf().read().cpu_hs_div_num().bits(); - if cpu_hs_div == 0 && force_120m { - return 4; - } - let hp_root_hs_div = pcr().sysclk_conf().read().hs_div_num().bits(); - (hp_root_hs_div + 1) * (cpu_hs_div + 1) + let force_120m = PCR::regs().cpu_freq_conf().read().cpu_hs_120m_force().bit(); + let cpu_hs_div = PCR::regs().cpu_freq_conf().read().cpu_hs_div_num().bits(); + if cpu_hs_div == 0 && force_120m { + return 4; } + let hp_root_hs_div = PCR::regs().sysclk_conf().read().hs_div_num().bits(); + (hp_root_hs_div + 1) * (cpu_hs_div + 1) } // clk_ll_bbpll_get_freq_mhz @@ -543,54 +440,43 @@ pub(super) fn reset_mac() { pub(super) fn init_clocks() { unsafe { - let pmu = PMU::regs(); - - pmu.hp_sleep_icg_modem() + PMU::regs() + .hp_sleep_icg_modem() .modify(|_, w| w.hp_sleep_dig_icg_modem_code().bits(0)); - pmu.hp_modem_icg_modem() + PMU::regs() + .hp_modem_icg_modem() .modify(|_, w| w.hp_modem_dig_icg_modem_code().bits(1)); - pmu.hp_active_icg_modem() + PMU::regs() + .hp_active_icg_modem() .modify(|_, w| w.hp_active_dig_icg_modem_code().bits(2)); - pmu.imm_modem_icg() + PMU::regs() + .imm_modem_icg() .write(|w| w.update_dig_icg_modem_en().set_bit()); - pmu.imm_sleep_sysclk() + PMU::regs() + .imm_sleep_sysclk() .write(|w| w.update_dig_icg_switch().set_bit()); MODEM_SYSCON::regs().clk_conf_power_st().modify(|_, w| { - w.clk_modem_apb_st_map() - .bits(6) - .clk_modem_peri_st_map() - .bits(4) - .clk_wifi_st_map() - .bits(6) - .clk_bt_st_map() - .bits(6) - .clk_fe_st_map() - .bits(6) - .clk_zb_st_map() - .bits(6) + w.clk_modem_apb_st_map().bits(6); + w.clk_modem_peri_st_map().bits(4); + w.clk_wifi_st_map().bits(6); + w.clk_bt_st_map().bits(6); + w.clk_fe_st_map().bits(6); + w.clk_zb_st_map().bits(6) }); MODEM_LPCON::regs().clk_conf_power_st().modify(|_, w| { - w.clk_lp_apb_st_map() - .bits(6) - .clk_i2c_mst_st_map() - .bits(6) - .clk_coex_st_map() - .bits(6) - .clk_wifipwr_st_map() - .bits(6) + w.clk_lp_apb_st_map().bits(6); + w.clk_i2c_mst_st_map().bits(6); + w.clk_coex_st_map().bits(6); + w.clk_wifipwr_st_map().bits(6) }); MODEM_LPCON::regs().wifi_lp_clk_conf().modify(|_, w| { - w.clk_wifipwr_lp_sel_osc_slow() - .set_bit() - .clk_wifipwr_lp_sel_osc_fast() - .set_bit() - .clk_wifipwr_lp_sel_xtal32k() - .set_bit() - .clk_wifipwr_lp_sel_xtal() - .set_bit() + w.clk_wifipwr_lp_sel_osc_slow().set_bit(); + w.clk_wifipwr_lp_sel_osc_fast().set_bit(); + w.clk_wifipwr_lp_sel_xtal32k().set_bit(); + w.clk_wifipwr_lp_sel_xtal().set_bit() }); MODEM_LPCON::regs() diff --git a/esp-hal/src/clock/clocks_ll/esp32h2.rs b/esp-hal/src/clock/clocks_ll/esp32h2.rs index c7e9f482cb..f6a9a53627 100644 --- a/esp-hal/src/clock/clocks_ll/esp32h2.rs +++ b/esp-hal/src/clock/clocks_ll/esp32h2.rs @@ -1,6 +1,6 @@ use crate::{ clock::{ApbClock, Clock, CpuClock, PllClock, XtalClock}, - peripherals::{LP_AON, MODEM_LPCON, MODEM_SYSCON, PCR, PMU}, + peripherals::{I2C_ANA_MST, LP_AON, MODEM_LPCON, MODEM_SYSCON, PCR, PMU}, }; const I2C_BBPLL: u8 = 0x66; @@ -21,20 +21,9 @@ const I2C_BBPLL_OC_DLREF_SEL: u8 = 5; const I2C_BBPLL_OC_DLREF_SEL_MSB: u8 = 7; const I2C_BBPLL_OC_DLREF_SEL_LSB: u8 = 6; -const I2C_MST_ANA_CONF0_REG: u32 = 0x600AD800 + 0x18; -const I2C_MST_BBPLL_STOP_FORCE_HIGH: u32 = 1 << 2; -const I2C_MST_BBPLL_STOP_FORCE_LOW: u32 = 1 << 3; -const I2C_MST_BBPLL_CAL_DONE: u32 = 1 << 24; - -const MODEM_LPCON_CLK_CONF_FORCE_ON_REG: u32 = DR_REG_MODEM_LPCON_BASE + 0xc; -const MODEM_LPCON_CLK_I2C_MST_FO: u32 = 1 << 2; - // May be needed for enabling I2C clock -const MODEM_LPCON_I2C_CLK_CONF_REG: u32 = DR_REG_MODEM_LPCON_BASE + 0x8; const MODEM_LPCON_CLK_I2C_SEL_96M: u32 = 1 << 0; -const DR_REG_MODEM_LPCON_BASE: u32 = 0x600AD000; - const REGI2C_BBPLL: u8 = 0x66; const REGI2C_BIAS: u8 = 0x6a; const REGI2C_PMU: u8 = 0x6d; @@ -42,101 +31,81 @@ const REGI2C_ULP_CAL: u8 = 0x61; const REGI2C_SAR_I2C: u8 = 0x69; const I2C_MST_ANA_CONF1_M: u32 = 0x00FFFFFF; -const I2C_MST_ANA_CONF1_REG: u32 = I2C_MST_I2C0_CTRL_REG + 0x1c; -const REGI2C_BBPLL_RD_MASK: u32 = !(1 << 7) & I2C_MST_ANA_CONF1_M; -const REGI2C_BIAS_RD_MASK: u32 = !(1 << 6) & I2C_MST_ANA_CONF1_M; -const REGI2C_DIG_REG_RD_MASK: u32 = !(1 << 10) & I2C_MST_ANA_CONF1_M; -const REGI2C_ULP_CAL_RD_MASK: u32 = !(1 << 8) & I2C_MST_ANA_CONF1_M; -const REGI2C_SAR_I2C_RD_MASK: u32 = !(1 << 9) & I2C_MST_ANA_CONF1_M; +pub(crate) fn esp32h2_rtc_bbpll_configure(_xtal_freq: XtalClock, _pll_freq: PllClock) { + // Enable I2C master clock + MODEM_LPCON::regs() + .clk_conf_force_on() + .modify(|_, w| w.clk_i2c_mst_fo().set_bit()); -const REGI2C_RTC_SLAVE_ID_V: u8 = 0xFF; -const REGI2C_RTC_SLAVE_ID_S: u8 = 0; -const REGI2C_RTC_ADDR_V: u8 = 0xFF; -const REGI2C_RTC_ADDR_S: u8 = 8; -const REGI2C_RTC_WR_CNTL_S: u8 = 24; -const REGI2C_RTC_DATA_V: u8 = 0xFF; -const REGI2C_RTC_DATA_S: u8 = 16; + // Set I2C clock to 96MHz + MODEM_LPCON::regs() + .clk_conf() + .modify(|r, w| unsafe { w.bits(r.bits() | MODEM_LPCON_CLK_I2C_SEL_96M) }); -const I2C_MST_I2C0_CTRL_REG: u32 = 0x600AD800; -const REGI2C_RTC_BUSY: u32 = 1 << 25; + // BPPLL calibration start + I2C_ANA_MST::regs().ana_conf0().modify(|_, w| { + w.bbpll_stop_force_high().clear_bit(); + w.bbpll_stop_force_low().set_bit() + }); -pub(crate) fn esp32h2_rtc_bbpll_configure(_xtal_freq: XtalClock, _pll_freq: PllClock) { - unsafe { - // Enable I2C master clock - (MODEM_LPCON_CLK_CONF_FORCE_ON_REG as *mut u32).write_volatile( - (MODEM_LPCON_CLK_CONF_FORCE_ON_REG as *mut u32).read_volatile() - | MODEM_LPCON_CLK_I2C_MST_FO, - ); - - // Set I2C clock to 96MHz - (MODEM_LPCON_I2C_CLK_CONF_REG as *mut u32).write_volatile( - (MODEM_LPCON_I2C_CLK_CONF_REG as *mut u32).read_volatile() - | MODEM_LPCON_CLK_I2C_SEL_96M, - ); - - let i2c_mst_ana_conf0_reg_ptr = I2C_MST_ANA_CONF0_REG as *mut u32; - - // BPPLL calibration start - i2c_mst_ana_conf0_reg_ptr.write_volatile( - i2c_mst_ana_conf0_reg_ptr.read_volatile() & !I2C_MST_BBPLL_STOP_FORCE_HIGH, - ); - i2c_mst_ana_conf0_reg_ptr.write_volatile( - i2c_mst_ana_conf0_reg_ptr.read_volatile() | I2C_MST_BBPLL_STOP_FORCE_LOW, - ); - - let oc_ref_div = 0u32; - let oc_div = 1u32; - let oc_dhref_sel = 3u32; - let oc_dlref_sel = 1u32; - - regi2c_write_mask( - I2C_BBPLL, - I2C_BBPLL_HOSTID, - I2C_BBPLL_OC_REF_DIV, - I2C_BBPLL_OC_REF_DIV_MSB, - I2C_BBPLL_OC_REF_DIV_LSB, - oc_ref_div as u8, - ); - - regi2c_write_mask( - I2C_BBPLL, - I2C_BBPLL_HOSTID, - I2C_BBPLL_OC_DIV, - I2C_BBPLL_OC_DIV_MSB, - I2C_BBPLL_OC_DIV_LSB, - oc_div as u8, - ); - - regi2c_write_mask( - I2C_BBPLL, - I2C_BBPLL_HOSTID, - I2C_BBPLL_OC_DHREF_SEL, - I2C_BBPLL_OC_DHREF_SEL_MSB, - I2C_BBPLL_OC_DHREF_SEL_LSB, - oc_dhref_sel as u8, - ); - - regi2c_write_mask( - I2C_BBPLL, - I2C_BBPLL_HOSTID, - I2C_BBPLL_OC_DLREF_SEL, - I2C_BBPLL_OC_DLREF_SEL_MSB, - I2C_BBPLL_OC_DLREF_SEL_LSB, - oc_dlref_sel as u8, - ); - - // WAIT CALIBRATION DONE - while (i2c_mst_ana_conf0_reg_ptr.read_volatile() & I2C_MST_BBPLL_CAL_DONE) == 0 {} - - // BBPLL CALIBRATION STOP - i2c_mst_ana_conf0_reg_ptr.write_volatile( - i2c_mst_ana_conf0_reg_ptr.read_volatile() | I2C_MST_BBPLL_STOP_FORCE_HIGH, - ); - i2c_mst_ana_conf0_reg_ptr.write_volatile( - i2c_mst_ana_conf0_reg_ptr.read_volatile() & !I2C_MST_BBPLL_STOP_FORCE_LOW, - ); - } + let oc_ref_div = 0; + let oc_div = 1; + let oc_dhref_sel = 3; + let oc_dlref_sel = 1; + + regi2c_write_mask( + I2C_BBPLL, + I2C_BBPLL_HOSTID, + I2C_BBPLL_OC_REF_DIV, + I2C_BBPLL_OC_REF_DIV_MSB, + I2C_BBPLL_OC_REF_DIV_LSB, + oc_ref_div, + ); + + regi2c_write_mask( + I2C_BBPLL, + I2C_BBPLL_HOSTID, + I2C_BBPLL_OC_DIV, + I2C_BBPLL_OC_DIV_MSB, + I2C_BBPLL_OC_DIV_LSB, + oc_div, + ); + + regi2c_write_mask( + I2C_BBPLL, + I2C_BBPLL_HOSTID, + I2C_BBPLL_OC_DHREF_SEL, + I2C_BBPLL_OC_DHREF_SEL_MSB, + I2C_BBPLL_OC_DHREF_SEL_LSB, + oc_dhref_sel, + ); + + regi2c_write_mask( + I2C_BBPLL, + I2C_BBPLL_HOSTID, + I2C_BBPLL_OC_DLREF_SEL, + I2C_BBPLL_OC_DLREF_SEL_MSB, + I2C_BBPLL_OC_DLREF_SEL_LSB, + oc_dlref_sel, + ); + + // WAIT CALIBRATION DONE + while I2C_ANA_MST::regs() + .ana_conf0() + .read() + .cal_done() + .bit_is_clear() + {} + + // workaround bbpll calibration might stop early + crate::rom::ets_delay_us(10); + + // BBPLL CALIBRATION STOP + I2C_ANA_MST::regs().ana_conf0().modify(|_, w| { + w.bbpll_stop_force_high().set_bit(); + w.bbpll_stop_force_low().clear_bit() + }); } pub(crate) fn esp32h2_rtc_bbpll_enable() { @@ -151,21 +120,19 @@ pub(crate) fn esp32h2_rtc_bbpll_enable() { .modify(|_, w| w.tie_high_global_bbpll_icg().set_bit()); } -pub(crate) fn esp32h2_rtc_update_to_xtal(freq: XtalClock, _div: u8) { +pub(crate) fn esp32h2_rtc_update_to_xtal(freq: XtalClock, div: u8) { 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); - - unsafe { - PCR::regs() - .cpu_freq_conf() - .modify(|_, w| w.cpu_div_num().bits(_div - 1)); - // Switch clock source - PCR::regs() - .sysclk_conf() - .modify(|_, w| w.soc_clk_sel().bits(0)); - } + clk_ll_ahb_set_divider(div as u32); + + PCR::regs() + .cpu_freq_conf() + .modify(|_, w| unsafe { w.cpu_div_num().bits(div - 1) }); + // Switch clock source + PCR::regs() + .sysclk_conf() + .modify(|_, w| unsafe { w.soc_clk_sel().bits(0) }); clk_ll_bus_update(); } @@ -174,19 +141,16 @@ pub(crate) fn esp32h2_rtc_freq_to_pll_mhz(cpu_clock_speed: CpuClock) { let cpu_divider = 96 / cpu_clock_speed.mhz(); clk_ll_cpu_set_divider(cpu_divider); let ahb_divider = match cpu_divider { - 1 => 3, - 2 => 4, + 1 | 2 => cpu_divider + 2, _ => cpu_divider, }; clk_ll_ahb_set_divider(ahb_divider); - unsafe { - PCR::regs() - .sysclk_conf() - .modify(|_, w| w.soc_clk_sel().bits(1)); + PCR::regs() + .sysclk_conf() + .modify(|_, w| unsafe { w.soc_clk_sel().bits(1) }); - clk_ll_bus_update(); - } + clk_ll_bus_update(); crate::rom::ets_update_cpu_frequency_rom(cpu_clock_speed.mhz()); } @@ -203,21 +167,17 @@ pub(crate) fn esp32h2_rtc_apb_freq_update(apb_freq: ApbClock) { fn clk_ll_cpu_set_divider(divider: u32) { assert!(divider >= 1); - unsafe { - PCR::regs() - .cpu_freq_conf() - .modify(|_, w| w.cpu_div_num().bits((divider - 1) as u8)); - } + PCR::regs() + .cpu_freq_conf() + .modify(|_, w| unsafe { w.cpu_div_num().bits((divider - 1) as u8) }); } fn clk_ll_ahb_set_divider(divider: u32) { assert!(divider >= 1); - unsafe { - PCR::regs() - .ahb_freq_conf() - .modify(|_, w| w.ahb_div_num().bits((divider - 1) as u8)); - } + PCR::regs() + .ahb_freq_conf() + .modify(|_, w| unsafe { w.ahb_div_num().bits((divider - 1) as u8) }); } fn clk_ll_bus_update() { @@ -234,95 +194,69 @@ fn clk_ll_bus_update() { {} } -fn regi2c_enable_block(block: u8) { - crate::peripherals::MODEM_LPCON::regs() +fn regi2c_enable_block(block: u8) -> usize { + MODEM_LPCON::regs() .clk_conf() .modify(|_, w| w.clk_i2c_mst_en().set_bit()); // Before config I2C register, enable corresponding slave. - - let en_mask = match block { - v if v == REGI2C_BBPLL => REGI2C_BBPLL_RD_MASK, - v if v == REGI2C_BIAS => REGI2C_BIAS_RD_MASK, - v if v == REGI2C_PMU => REGI2C_DIG_REG_RD_MASK, - v if v == REGI2C_ULP_CAL => REGI2C_ULP_CAL_RD_MASK, - v if v == REGI2C_SAR_I2C => REGI2C_SAR_I2C_RD_MASK, - _ => return, + let i2c_sel_bits = I2C_ANA_MST::regs().ana_conf2().read(); + let i2c_sel = match block { + v if v == REGI2C_BBPLL => i2c_sel_bits.bbpll_mst_sel().bit_is_set(), + v if v == REGI2C_BIAS => i2c_sel_bits.bias_mst_sel().bit_is_set(), + v if v == REGI2C_PMU => i2c_sel_bits.dig_reg_mst_sel().bit_is_set(), + v if v == REGI2C_ULP_CAL => i2c_sel_bits.ulp_cal_mst_sel().bit_is_set(), + v if v == REGI2C_SAR_I2C => i2c_sel_bits.sar_i2c_mst_sel().bit_is_set(), + _ => unreachable!(), }; - reg_set_bit(I2C_MST_ANA_CONF1_REG, en_mask) -} - -fn regi2c_disable_block(block: u8) { - let en_mask = match block { - v if v == REGI2C_BBPLL => REGI2C_BBPLL_RD_MASK, - v if v == REGI2C_BIAS => REGI2C_BIAS_RD_MASK, - v if v == REGI2C_PMU => REGI2C_DIG_REG_RD_MASK, - v if v == REGI2C_ULP_CAL => REGI2C_ULP_CAL_RD_MASK, - v if v == REGI2C_SAR_I2C => REGI2C_SAR_I2C_RD_MASK, - _ => return, - }; - reg_clr_bit(I2C_MST_ANA_CONF1_REG, en_mask) -} - -fn reg_set_bit(reg: u32, bit: u32) { - unsafe { - (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() | bit); - } -} - -fn reg_clr_bit(reg: u32, bit: u32) { - unsafe { - (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() & !bit); - } -} + I2C_ANA_MST::regs().ana_conf1().write(|w| unsafe { + w.bits(I2C_MST_ANA_CONF1_M); + match block { + v if v == REGI2C_BBPLL => w.bbpll_rd().clear_bit(), + v if v == REGI2C_BIAS => w.bias_rd().clear_bit(), + v if v == REGI2C_PMU => w.dig_reg_rd().clear_bit(), + v if v == REGI2C_ULP_CAL => w.ulp_cal_rd().clear_bit(), + v if v == REGI2C_SAR_I2C => w.sar_i2c_rd().clear_bit(), + _ => unreachable!(), + } + }); -fn reg_write(reg: u32, v: u32) { - unsafe { - (reg as *mut u32).write_volatile(v); + if i2c_sel { + 0 + } else { + 1 } } -fn reg_get_bit(reg: u32, b: u32) -> u32 { - unsafe { (reg as *mut u32).read_volatile() & b } -} - -fn reg_get_field(reg: u32, s: u32, v: u32) -> u32 { - unsafe { ((reg as *mut u32).read_volatile() >> s) & v } -} - pub(crate) fn regi2c_write_mask(block: u8, _host_id: u8, reg_add: u8, msb: u8, lsb: u8, data: u8) { assert!(msb < 8 + lsb); - regi2c_enable_block(block); - - let block_shifted = (block as u32 & REGI2C_RTC_SLAVE_ID_V as u32) << REGI2C_RTC_SLAVE_ID_S; - let reg_add_shifted = (reg_add as u32 & REGI2C_RTC_ADDR_V as u32) << REGI2C_RTC_ADDR_S; - let write_bit = 1u32 << REGI2C_RTC_WR_CNTL_S; + let master = regi2c_enable_block(block); // Read the i2c bus register - while reg_get_bit(I2C_MST_I2C0_CTRL_REG, REGI2C_RTC_BUSY) != 0 {} - - reg_write(I2C_MST_I2C0_CTRL_REG, block_shifted | reg_add_shifted); - while reg_get_bit(I2C_MST_I2C0_CTRL_REG, REGI2C_RTC_BUSY) != 0 {} - let mut temp = reg_get_field( - I2C_MST_I2C0_CTRL_REG, - REGI2C_RTC_DATA_S as u32, - REGI2C_RTC_DATA_V as u32, - ); - - // Mask the value field - temp &= (!(0xFFFFFFFF << lsb)) | (0xFFFFFFFF << (msb + 1)); - - // Write the value into the temporary - temp |= (data as u32 & (!(0xFFFFFFFF << (msb - lsb + 1)))) << lsb; + I2C_ANA_MST::regs().i2c_ctrl(master).write(|w| unsafe { + w.slave_addr().bits(block); + w.slave_reg_addr().bits(reg_add) + }); - let new_value = (temp & REGI2C_RTC_DATA_V as u32) << REGI2C_RTC_DATA_S; - reg_write( - I2C_MST_I2C0_CTRL_REG, - block_shifted | reg_add_shifted | write_bit | new_value, - ); - while reg_get_bit(I2C_MST_I2C0_CTRL_REG, REGI2C_RTC_BUSY) != 0 {} + while I2C_ANA_MST::regs().i2c_ctrl(master).read().busy().bit() {} + + // Example: LSB=2, MSB = 5 + // unwritten_bits = 1100 0011 + // data_mask = 0000 1111 + // data_bits = 00xx xx00 + let unwritten_bits = !(u8::MAX << lsb) | (u8::MAX << (msb + 1)); + let data_mask = !(u8::MAX << (msb - lsb + 1)); + let data_bits = (data & data_mask) << lsb; + + I2C_ANA_MST::regs().i2c_ctrl(master).modify(|r, w| unsafe { + w.slave_addr().bits(block); + w.slave_reg_addr().bits(reg_add); + w.read_write().set_bit(); + w.data() + .bits((r.data().bits() & unwritten_bits) | data_bits) + }); - regi2c_disable_block(block); + while I2C_ANA_MST::regs().i2c_ctrl(master).read().busy().bit() {} } pub(super) fn enable_phy(en: bool) { @@ -365,29 +299,27 @@ pub(super) fn reset_mac() { } pub(super) fn init_clocks() { - unsafe { - let pmu = PMU::regs(); - - pmu.hp_sleep_icg_modem() - .modify(|_, w| w.hp_sleep_dig_icg_modem_code().bits(0)); - pmu.hp_modem_icg_modem() - .modify(|_, w| w.hp_modem_dig_icg_modem_code().bits(1)); - pmu.hp_active_icg_modem() - .modify(|_, w| w.hp_active_dig_icg_modem_code().bits(2)); - pmu.imm_modem_icg() - .write(|w| w.update_dig_icg_modem_en().set_bit()); - pmu.imm_sleep_sysclk() - .write(|w| w.update_dig_icg_switch().set_bit()); - - MODEM_LPCON::regs().clk_conf().modify(|_, w| { - w.clk_i2c_mst_en() - .set_bit() - .clk_coex_en() - .set_bit() - .clk_fe_mem_en() - .set_bit() - }); - } + PMU::regs() + .hp_sleep_icg_modem() + .modify(|_, w| unsafe { w.hp_sleep_dig_icg_modem_code().bits(0) }); + PMU::regs() + .hp_modem_icg_modem() + .modify(|_, w| unsafe { w.hp_modem_dig_icg_modem_code().bits(1) }); + PMU::regs() + .hp_active_icg_modem() + .modify(|_, w| unsafe { w.hp_active_dig_icg_modem_code().bits(2) }); + PMU::regs() + .imm_modem_icg() + .write(|w| w.update_dig_icg_modem_en().set_bit()); + PMU::regs() + .imm_sleep_sysclk() + .write(|w| w.update_dig_icg_switch().set_bit()); + + MODEM_LPCON::regs().clk_conf().modify(|_, w| { + w.clk_i2c_mst_en().set_bit(); + w.clk_coex_en().set_bit(); + w.clk_fe_mem_en().set_bit() + }); } pub(super) fn ble_rtc_clk_init() { diff --git a/esp-hal/src/clock/clocks_ll/esp32s2.rs b/esp-hal/src/clock/clocks_ll/esp32s2.rs index 46fa4ebf43..6d460f9141 100644 --- a/esp-hal/src/clock/clocks_ll/esp32s2.rs +++ b/esp-hal/src/clock/clocks_ll/esp32s2.rs @@ -1,46 +1,44 @@ -use crate::{clock::CpuClock, peripherals::SYSCON}; +use crate::{ + clock::CpuClock, + peripherals::{LPWR, SYSCON, SYSTEM}, +}; const MHZ: u32 = 1000000; const UINT16_MAX: u32 = 0xffff; -const RTC_CNTL_DBIAS_1V25: u32 = 7; +const RTC_CNTL_DBIAS_1V25: u8 = 7; // when not running with 80MHz Flash frequency we could use RTC_CNTL_DBIAS_1V10 // for DIG_DBIAS_80M_160M - but RTC_CNTL_DBIAS_1V25 shouldn't hurt -const DIG_DBIAS_80M_160M: u32 = RTC_CNTL_DBIAS_1V25; -const DIG_DBIAS_240M: u32 = RTC_CNTL_DBIAS_1V25; +const DIG_DBIAS_80M_160M: u8 = RTC_CNTL_DBIAS_1V25; +const DIG_DBIAS_240M: u8 = RTC_CNTL_DBIAS_1V25; pub(crate) fn set_cpu_clock(cpu_clock_speed: CpuClock) { - let system_control = crate::peripherals::SYSTEM::regs(); - let rtc_cntl = crate::peripherals::LPWR::regs(); - - unsafe { - system_control - .sysclk_conf() - .modify(|_, w| w.soc_clk_sel().bits(1)); - system_control.cpu_per_conf().modify(|_, w| { - w.pll_freq_sel() - .set_bit() - .cpuperiod_sel() - .bits(match cpu_clock_speed { - CpuClock::_80MHz => 0, - CpuClock::_160MHz => 1, - CpuClock::_240MHz => 2, - }) - }); + SYSTEM::regs() + .sysclk_conf() + .modify(|_, w| unsafe { w.soc_clk_sel().bits(1) }); + SYSTEM::regs().cpu_per_conf().modify(|_, w| unsafe { + w.pll_freq_sel().set_bit(); + w.cpuperiod_sel().bits(match cpu_clock_speed { + CpuClock::_80MHz => 0, + CpuClock::_160MHz => 1, + CpuClock::_240MHz => 2, + }) + }); - rtc_cntl.reg().modify(|_, w| { - w.dig_reg_dbias_wak().bits(match cpu_clock_speed { - CpuClock::_80MHz => DIG_DBIAS_80M_160M, - CpuClock::_160MHz => DIG_DBIAS_80M_160M, - CpuClock::_240MHz => DIG_DBIAS_240M, - } as u8) - }); + LPWR::regs().reg().modify(|_, w| unsafe { + w.dig_reg_dbias_wak().bits(match cpu_clock_speed { + CpuClock::_80MHz => DIG_DBIAS_80M_160M, + CpuClock::_160MHz => DIG_DBIAS_80M_160M, + CpuClock::_240MHz => DIG_DBIAS_240M, + }) + }); - // FIXME untangle this - let value = (((80 * MHZ) >> 12) & UINT16_MAX) | ((((80 * MHZ) >> 12) & UINT16_MAX) << 16); - rtc_cntl.store5().modify(|_, w| w.scratch5().bits(value)); - } + // FIXME untangle this + let value = (((80 * MHZ) >> 12) & UINT16_MAX) | ((((80 * MHZ) >> 12) & UINT16_MAX) << 16); + LPWR::regs() + .store5() + .modify(|_, w| unsafe { w.scratch5().bits(value) }); } // Mask for clock bits used by both WIFI and Bluetooth, bit 0, 3, 6, 7, 8, 9 @@ -72,13 +70,12 @@ pub(super) fn enable_wifi(enable: bool) { } pub(super) fn reset_mac() { - const SYSTEM_MAC_RST: u32 = 1 << 2; SYSCON::regs() .wifi_rst_en() - .modify(|r, w| unsafe { w.wifi_rst().bits(r.wifi_rst().bits() | SYSTEM_MAC_RST) }); + .modify(|_, w| w.mac_rst().set_bit()); SYSCON::regs() .wifi_rst_en() - .modify(|r, w| unsafe { w.wifi_rst().bits(r.wifi_rst().bits() & !SYSTEM_MAC_RST) }); + .modify(|_, w| w.mac_rst().clear_bit()); } pub(super) fn init_clocks() { diff --git a/esp-hal/src/clock/clocks_ll/esp32s3.rs b/esp-hal/src/clock/clocks_ll/esp32s3.rs index 20e279ddfd..bf3ebaf371 100644 --- a/esp-hal/src/clock/clocks_ll/esp32s3.rs +++ b/esp-hal/src/clock/clocks_ll/esp32s3.rs @@ -1,27 +1,21 @@ use crate::{ clock::{Clock, CpuClock}, - peripherals::APB_CTRL, + peripherals::{APB_CTRL, SYSTEM}, rom, }; pub(crate) fn set_cpu_clock(cpu_clock_speed: CpuClock) { - let system_control = crate::peripherals::SYSTEM::regs(); - - unsafe { - system_control - .sysclk_conf() - .modify(|_, w| w.soc_clk_sel().bits(1)); - system_control.cpu_per_conf().modify(|_, w| { - w.pll_freq_sel() - .set_bit() - .cpuperiod_sel() - .bits(match cpu_clock_speed { - CpuClock::_80MHz => 0, - CpuClock::_160MHz => 1, - CpuClock::_240MHz => 2, - }) - }); - } + SYSTEM::regs() + .sysclk_conf() + .modify(|_, w| unsafe { w.soc_clk_sel().bits(1) }); + SYSTEM::regs().cpu_per_conf().modify(|_, w| unsafe { + w.pll_freq_sel().set_bit(); + w.cpuperiod_sel().bits(match cpu_clock_speed { + CpuClock::_80MHz => 0, + CpuClock::_160MHz => 1, + CpuClock::_240MHz => 2, + }) + }); rom::ets_update_cpu_frequency_rom(cpu_clock_speed.frequency().as_mhz()); } @@ -57,13 +51,12 @@ pub(super) fn enable_wifi(_: bool) { } pub(super) fn reset_mac() { - const SYSTEM_MAC_RST: u32 = 1 << 2; APB_CTRL::regs() .wifi_rst_en() - .modify(|r, w| unsafe { w.bits(r.bits() | SYSTEM_MAC_RST) }); + .modify(|_, w| w.mac_rst().set_bit()); APB_CTRL::regs() .wifi_rst_en() - .modify(|r, w| unsafe { w.bits(r.bits() & !SYSTEM_MAC_RST) }); + .modify(|_, w| w.mac_rst().clear_bit()); } pub(super) fn init_clocks() { diff --git a/esp-hal/src/soc/esp32c6/peripherals.rs b/esp-hal/src/soc/esp32c6/peripherals.rs index a642bba64e..ce594ac0e0 100644 --- a/esp-hal/src/soc/esp32c6/peripherals.rs +++ b/esp-hal/src/soc/esp32c6/peripherals.rs @@ -41,6 +41,7 @@ crate::peripherals! { HMAC <= HMAC, HP_APM <= HP_APM, HP_SYS <= HP_SYS, + I2C_ANA_MST <= I2C_ANA_MST, I2S0 <= I2S0 (I2S0), IEEE802154 <= IEEE802154, INTERRUPT_CORE0 <= INTERRUPT_CORE0, diff --git a/esp-hal/src/soc/esp32h2/peripherals.rs b/esp-hal/src/soc/esp32h2/peripherals.rs index 26bb27ad39..f59aac825f 100644 --- a/esp-hal/src/soc/esp32h2/peripherals.rs +++ b/esp-hal/src/soc/esp32h2/peripherals.rs @@ -39,6 +39,7 @@ crate::peripherals! { HMAC <= HMAC, HP_APM <= HP_APM, HP_SYS <= HP_SYS, + I2C_ANA_MST <= I2C_ANA_MST, I2S0 <= I2S0 (I2S0), IEEE802154 <= IEEE802154, INTERRUPT_CORE0 <= INTERRUPT_CORE0,