mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-09-30 22:01:11 +00:00
Clean up clocks_ll (#3101)
This commit is contained in:
parent
477e1d6521
commit
dc4daa9217
@ -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 = "0f3ea9f", optional = true }
|
||||
esp32c2 = { version = "0.24.0", features = ["critical-section", "rt"], git = "https://github.com/esp-rs/esp-pacs", rev = "0f3ea9f", optional = true }
|
||||
esp32c3 = { version = "0.27.0", features = ["critical-section", "rt"], git = "https://github.com/esp-rs/esp-pacs", rev = "0f3ea9f", optional = true }
|
||||
esp32c6 = { version = "0.18.0", features = ["critical-section", "rt"], git = "https://github.com/esp-rs/esp-pacs", rev = "0f3ea9f", optional = true }
|
||||
esp32h2 = { version = "0.14.0", features = ["critical-section", "rt"], git = "https://github.com/esp-rs/esp-pacs", rev = "0f3ea9f", optional = true }
|
||||
esp32s2 = { version = "0.26.0", features = ["critical-section", "rt"], git = "https://github.com/esp-rs/esp-pacs", rev = "0f3ea9f", optional = true }
|
||||
esp32s3 = { version = "0.30.0", features = ["critical-section", "rt"], git = "https://github.com/esp-rs/esp-pacs", rev = "0f3ea9f", optional = true }
|
||||
|
||||
[target.'cfg(target_arch = "riscv32")'.dependencies]
|
||||
riscv = { version = "0.12.1" }
|
||||
|
@ -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,46 +166,42 @@ 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();
|
||||
|
||||
unsafe {
|
||||
let value = (((freq.hz()) >> 12) & UINT16_MAX) | ((((freq.hz()) >> 12) & UINT16_MAX) << 16);
|
||||
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| {
|
||||
APB_CTRL::regs().sysclk_conf().modify(|_, w| unsafe {
|
||||
w.pre_div_cnt()
|
||||
.bits(((freq.hz()) / REF_CLK_FREQ - 1) as u16)
|
||||
});
|
||||
|
||||
// adjust ref_tick
|
||||
apb_cntl.xtal_tick_conf().modify(|_, w| {
|
||||
APB_CTRL::regs().xtal_tick_conf().modify(|_, w| unsafe {
|
||||
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));
|
||||
LPWR::regs()
|
||||
.clk_conf()
|
||||
.modify(|_, w| w.soc_clk_sel().xtal());
|
||||
LPWR::regs()
|
||||
.store5()
|
||||
.modify(|_, w| unsafe { w.scratch5().bits(value) });
|
||||
|
||||
// lower the voltage
|
||||
rtc_cntl
|
||||
LPWR::regs()
|
||||
.reg()
|
||||
.modify(|_, w| w.dig_dbias_wak().bits(DIG_DBIAS_XTAL as u8));
|
||||
}
|
||||
.modify(|_, w| unsafe { w.dig_dbias_wak().bits(DIG_DBIAS_XTAL as u8) });
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
unsafe {
|
||||
const RTC_CNTL_DBIAS_1V25: u32 = 7;
|
||||
|
||||
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;
|
||||
|
||||
const CPU_80M: u32 = 0;
|
||||
@ -232,18 +225,19 @@ pub(crate) fn set_cpu_freq(cpu_freq_mhz: crate::clock::CpuClock) {
|
||||
}
|
||||
|
||||
let value = (((80 * MHZ) >> 12) & UINT16_MAX) | ((((80 * MHZ) >> 12) & UINT16_MAX) << 16);
|
||||
dport
|
||||
DPORT::regs()
|
||||
.cpu_per_conf()
|
||||
.write(|w| w.cpuperiod_sel().bits(per_conf as u8));
|
||||
rtc_cntl
|
||||
.write(|w| unsafe { w.cpuperiod_sel().bits(per_conf as u8) });
|
||||
LPWR::regs()
|
||||
.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));
|
||||
.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
|
||||
/// will be accurate. Call this function when CPU frequency is changed.
|
||||
@ -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() {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
clock::{ApbClock, Clock, CpuClock, PllClock, XtalClock},
|
||||
peripherals::{APB_CTRL, MODEM_CLKRST},
|
||||
peripherals::{APB_CTRL, I2C_ANA_MST, LPWR, MODEM_CLKRST, SYSTEM},
|
||||
rom::{regi2c_write, regi2c_write_mask},
|
||||
};
|
||||
|
||||
@ -31,13 +31,7 @@ const I2C_BBPLL_OC_DHREF_SEL_LSB: u32 = 4;
|
||||
|
||||
const I2C_BBPLL_OC_DLREF_SEL_LSB: u32 = 6;
|
||||
|
||||
const I2C_MST_ANA_CONF0_REG: u32 = 0x6004_E840;
|
||||
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;
|
||||
@ -46,23 +40,16 @@ pub(crate) fn esp32c2_rtc_bbpll_configure(xtal_freq: XtalClock, _pll_freq: PllCl
|
||||
let dcur: u32;
|
||||
let dbias: u32;
|
||||
|
||||
unsafe {
|
||||
let clear_reg_mask = |reg, mask: u32| {
|
||||
(reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() & !mask)
|
||||
};
|
||||
let set_reg_mask = |reg, mask: u32| {
|
||||
(reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() | mask)
|
||||
};
|
||||
|
||||
clear_reg_mask(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_HIGH);
|
||||
set_reg_mask(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_LOW);
|
||||
}
|
||||
|
||||
// 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());
|
||||
|
||||
I2C_ANA_MST::regs().ana_conf0().modify(|_, w| {
|
||||
w.bbpll_stop_force_high().clear_bit();
|
||||
w.bbpll_stop_force_low().set_bit()
|
||||
});
|
||||
|
||||
// Configure 480M PLL
|
||||
match xtal_freq {
|
||||
XtalClock::_26M => {
|
||||
@ -103,69 +90,71 @@ pub(crate) fn esp32c2_rtc_bbpll_configure(xtal_freq: XtalClock, _pll_freq: PllCl
|
||||
regi2c_write!(I2C_BBPLL, I2C_BBPLL_OC_DCUR, i2c_bbpll_dcur);
|
||||
|
||||
regi2c_write_mask!(I2C_BBPLL, I2C_BBPLL_OC_VCO_DBIAS, dbias);
|
||||
}
|
||||
|
||||
pub(crate) fn esp32c2_rtc_bbpll_enable() {
|
||||
let rtc_cntl = crate::peripherals::LPWR::regs();
|
||||
// WAIT CALIBRATION DONE
|
||||
while I2C_ANA_MST::regs()
|
||||
.ana_conf0()
|
||||
.read()
|
||||
.bbpll_cal_done()
|
||||
.bit_is_clear()
|
||||
{}
|
||||
|
||||
rtc_cntl.options0().modify(|_, w| {
|
||||
w.bb_i2c_force_pd()
|
||||
.clear_bit()
|
||||
.bbpll_force_pd()
|
||||
.clear_bit()
|
||||
.bbpll_i2c_force_pd()
|
||||
.clear_bit()
|
||||
// workaround bbpll calibration might stop early
|
||||
crate::rom::ets_delay_us(10);
|
||||
|
||||
// Stop BBPLL self-calibration
|
||||
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 esp32c2_rtc_update_to_xtal(freq: XtalClock, _div: u32) {
|
||||
pub(crate) fn esp32c2_rtc_bbpll_enable() {
|
||||
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) {
|
||||
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)
|
||||
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_control
|
||||
SYSTEM::regs()
|
||||
.sysclk_conf()
|
||||
.modify(|_, w| w.soc_clk_sel().bits(0));
|
||||
}
|
||||
.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| {
|
||||
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 +188,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 +208,29 @@ 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());
|
||||
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());
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
clock::{ApbClock, Clock, CpuClock, PllClock, XtalClock},
|
||||
peripherals::{APB_CTRL, LPWR},
|
||||
peripherals::{APB_CTRL, I2C_ANA_MST, LPWR, SYSTEM},
|
||||
rom::{regi2c_write, regi2c_write_mask},
|
||||
};
|
||||
|
||||
@ -35,13 +35,7 @@ const I2C_BBPLL_OC_DLREF_SEL: u32 = 6;
|
||||
const I2C_BBPLL_OC_DLREF_SEL_MSB: u32 = 7;
|
||||
const I2C_BBPLL_OC_DLREF_SEL_LSB: u32 = 6;
|
||||
|
||||
const I2C_MST_ANA_CONF0_REG: u32 = 0x6000_e040;
|
||||
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;
|
||||
@ -50,24 +44,18 @@ pub(crate) fn esp32c3_rtc_bbpll_configure(xtal_freq: XtalClock, pll_freq: PllClo
|
||||
let dcur: u32;
|
||||
let dbias: u32;
|
||||
|
||||
unsafe {
|
||||
let clear_reg_mask = |reg, mask: u32| {
|
||||
(reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() & !mask)
|
||||
};
|
||||
let set_reg_mask = |reg, mask: u32| {
|
||||
(reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() | mask)
|
||||
};
|
||||
// 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))
|
||||
});
|
||||
|
||||
clear_reg_mask(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_HIGH);
|
||||
set_reg_mask(I2C_MST_ANA_CONF0_REG, 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()
|
||||
});
|
||||
|
||||
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());
|
||||
|
||||
// Configure 480M PLL
|
||||
match xtal_freq {
|
||||
XtalClock::_40M => {
|
||||
@ -103,11 +91,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 +150,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)
|
||||
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_control
|
||||
SYSTEM::regs()
|
||||
.sysclk_conf()
|
||||
.modify(|_, w| w.soc_clk_sel().bits(0));
|
||||
}
|
||||
.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| {
|
||||
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 +228,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;
|
||||
|
@ -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| {
|
||||
PCR::regs().cpu_freq_conf().modify(|_, w| unsafe {
|
||||
w.cpu_hs_div_num()
|
||||
.bits(((480 / cpu_clock_speed_mhz / 3) - 1) as u8)
|
||||
.cpu_hs_120m_force()
|
||||
.clear_bit()
|
||||
.bits(((480 / cpu_clock_speed_mhz / 3) - 1) as u8);
|
||||
w.cpu_hs_120m_force().clear_bit()
|
||||
});
|
||||
|
||||
pcr.cpu_freq_conf()
|
||||
PCR::regs()
|
||||
.cpu_freq_conf()
|
||||
.modify(|_, w| w.cpu_hs_120m_force().clear_bit());
|
||||
|
||||
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,215 +209,134 @@ 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)),
|
||||
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 I2C_MST_ANA_CONF1_M: u32 = 0x00FFFFFF;
|
||||
|
||||
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();
|
||||
|
||||
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,
|
||||
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!(),
|
||||
};
|
||||
|
||||
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)
|
||||
});
|
||||
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!(),
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
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 master = 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;
|
||||
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)
|
||||
});
|
||||
|
||||
let new_value = (data as u32) << REGI2C_RTC_DATA_S;
|
||||
|
||||
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()
|
||||
{}
|
||||
|
||||
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 master = 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)
|
||||
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() {}
|
||||
|
||||
let mut temp = lp_i2c_ana
|
||||
.i2c0_data()
|
||||
.read()
|
||||
.lp_i2c_ana_mast_i2c0_rdata()
|
||||
.bits() as u32;
|
||||
// Example: LSB=2, MSB = 5
|
||||
// unwritten_bits = 1100 0011
|
||||
// data_mask = 0000 1111
|
||||
// data_bits = 00xx xx00
|
||||
let unwritten_bits = (!(u32::MAX << lsb) | (u32::MAX << (msb + 1))) as u8;
|
||||
let data_mask = !(u32::MAX << (msb - lsb + 1)) as u8;
|
||||
let data_bits = (data & data_mask) << lsb;
|
||||
|
||||
// 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)
|
||||
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)
|
||||
});
|
||||
|
||||
while lp_i2c_ana
|
||||
.i2c0_ctrl()
|
||||
.read()
|
||||
.lp_i2c_ana_mast_i2c0_busy()
|
||||
.bit()
|
||||
{}
|
||||
|
||||
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()
|
||||
PCR::regs()
|
||||
.ahb_freq_conf()
|
||||
.modify(|_, w| w.ahb_ls_div_num().bits(div - 1));
|
||||
}
|
||||
.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()
|
||||
PCR::regs()
|
||||
.cpu_freq_conf()
|
||||
.modify(|_, w| w.cpu_ls_div_num().bits(div - 1));
|
||||
}
|
||||
.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();
|
||||
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();
|
||||
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().sysclk_conf().read().hs_div_num().bits();
|
||||
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
|
||||
pub(crate) fn esp32c6_bbpll_get_freq_mhz() -> u32 {
|
||||
@ -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()
|
||||
|
@ -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,53 +31,28 @@ 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;
|
||||
|
||||
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 I2C_MST_I2C0_CTRL_REG: u32 = 0x600AD800;
|
||||
const REGI2C_RTC_BUSY: u32 = 1 << 25;
|
||||
|
||||
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,
|
||||
);
|
||||
MODEM_LPCON::regs()
|
||||
.clk_conf_force_on()
|
||||
.modify(|_, w| w.clk_i2c_mst_fo().set_bit());
|
||||
|
||||
// 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;
|
||||
MODEM_LPCON::regs()
|
||||
.clk_conf()
|
||||
.modify(|r, w| unsafe { w.bits(r.bits() | MODEM_LPCON_CLK_I2C_SEL_96M) });
|
||||
|
||||
// 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,
|
||||
);
|
||||
I2C_ANA_MST::regs().ana_conf0().modify(|_, w| {
|
||||
w.bbpll_stop_force_high().clear_bit();
|
||||
w.bbpll_stop_force_low().set_bit()
|
||||
});
|
||||
|
||||
let oc_ref_div = 0u32;
|
||||
let oc_div = 1u32;
|
||||
let oc_dhref_sel = 3u32;
|
||||
let oc_dlref_sel = 1u32;
|
||||
let oc_ref_div = 0;
|
||||
let oc_div = 1;
|
||||
let oc_dhref_sel = 3;
|
||||
let oc_dlref_sel = 1;
|
||||
|
||||
regi2c_write_mask(
|
||||
I2C_BBPLL,
|
||||
@ -96,7 +60,7 @@ pub(crate) fn esp32h2_rtc_bbpll_configure(_xtal_freq: XtalClock, _pll_freq: PllC
|
||||
I2C_BBPLL_OC_REF_DIV,
|
||||
I2C_BBPLL_OC_REF_DIV_MSB,
|
||||
I2C_BBPLL_OC_REF_DIV_LSB,
|
||||
oc_ref_div as u8,
|
||||
oc_ref_div,
|
||||
);
|
||||
|
||||
regi2c_write_mask(
|
||||
@ -105,7 +69,7 @@ pub(crate) fn esp32h2_rtc_bbpll_configure(_xtal_freq: XtalClock, _pll_freq: PllC
|
||||
I2C_BBPLL_OC_DIV,
|
||||
I2C_BBPLL_OC_DIV_MSB,
|
||||
I2C_BBPLL_OC_DIV_LSB,
|
||||
oc_div as u8,
|
||||
oc_div,
|
||||
);
|
||||
|
||||
regi2c_write_mask(
|
||||
@ -114,7 +78,7 @@ pub(crate) fn esp32h2_rtc_bbpll_configure(_xtal_freq: XtalClock, _pll_freq: PllC
|
||||
I2C_BBPLL_OC_DHREF_SEL,
|
||||
I2C_BBPLL_OC_DHREF_SEL_MSB,
|
||||
I2C_BBPLL_OC_DHREF_SEL_LSB,
|
||||
oc_dhref_sel as u8,
|
||||
oc_dhref_sel,
|
||||
);
|
||||
|
||||
regi2c_write_mask(
|
||||
@ -123,20 +87,25 @@ pub(crate) fn esp32h2_rtc_bbpll_configure(_xtal_freq: XtalClock, _pll_freq: PllC
|
||||
I2C_BBPLL_OC_DLREF_SEL,
|
||||
I2C_BBPLL_OC_DLREF_SEL_MSB,
|
||||
I2C_BBPLL_OC_DLREF_SEL_LSB,
|
||||
oc_dlref_sel as u8,
|
||||
oc_dlref_sel,
|
||||
);
|
||||
|
||||
// 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_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().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);
|
||||
clk_ll_ahb_set_divider(div as u32);
|
||||
|
||||
unsafe {
|
||||
PCR::regs()
|
||||
.cpu_freq_conf()
|
||||
.modify(|_, w| w.cpu_div_num().bits(_div - 1));
|
||||
.modify(|_, w| unsafe { w.cpu_div_num().bits(div - 1) });
|
||||
// Switch clock source
|
||||
PCR::regs()
|
||||
.sysclk_conf()
|
||||
.modify(|_, w| w.soc_clk_sel().bits(0));
|
||||
}
|
||||
.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));
|
||||
.modify(|_, w| unsafe { w.soc_clk_sel().bits(1) });
|
||||
|
||||
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));
|
||||
}
|
||||
.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));
|
||||
}
|
||||
.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)
|
||||
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 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)
|
||||
if i2c_sel {
|
||||
0
|
||||
} else {
|
||||
1
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
fn reg_write(reg: u32, v: u32) {
|
||||
unsafe {
|
||||
(reg as *mut u32).write_volatile(v);
|
||||
}
|
||||
}
|
||||
|
||||
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 {}
|
||||
I2C_ANA_MST::regs().i2c_ctrl(master).write(|w| unsafe {
|
||||
w.slave_addr().bits(block);
|
||||
w.slave_reg_addr().bits(reg_add)
|
||||
});
|
||||
|
||||
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,
|
||||
);
|
||||
while I2C_ANA_MST::regs().i2c_ctrl(master).read().busy().bit() {}
|
||||
|
||||
// Mask the value field
|
||||
temp &= (!(0xFFFFFFFF << lsb)) | (0xFFFFFFFF << (msb + 1));
|
||||
// Example: LSB=2, MSB = 5
|
||||
// unwritten_bits = 1100 0011
|
||||
// data_mask = 0000 1111
|
||||
// data_bits = 00xx xx00
|
||||
let unwritten_bits = (!(u32::MAX << lsb) | (u32::MAX << (msb + 1))) as u8;
|
||||
let data_mask = !(u32::MAX << (msb - lsb + 1)) as u8;
|
||||
let data_bits = (data & data_mask) << lsb;
|
||||
|
||||
// Write the value into the temporary
|
||||
temp |= (data as u32 & (!(0xFFFFFFFF << (msb - lsb + 1)))) << 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)
|
||||
});
|
||||
|
||||
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 {}
|
||||
|
||||
regi2c_disable_block(block);
|
||||
while I2C_ANA_MST::regs().i2c_ctrl(master).read().busy().bit() {}
|
||||
}
|
||||
|
||||
pub(super) fn enable_phy(en: bool) {
|
||||
@ -365,30 +299,28 @@ 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()
|
||||
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.imm_sleep_sysclk()
|
||||
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()
|
||||
.clk_coex_en()
|
||||
.set_bit()
|
||||
.clk_fe_mem_en()
|
||||
.set_bit()
|
||||
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() {
|
||||
// nothing for this target (yet)
|
||||
|
@ -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
|
||||
SYSTEM::regs()
|
||||
.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 {
|
||||
.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| {
|
||||
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,
|
||||
} as u8)
|
||||
})
|
||||
});
|
||||
|
||||
// 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));
|
||||
}
|
||||
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() {
|
||||
|
@ -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
|
||||
SYSTEM::regs()
|
||||
.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 {
|
||||
.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() {
|
||||
|
@ -35,6 +35,7 @@ crate::peripherals! {
|
||||
EFUSE <= EFUSE,
|
||||
EXTMEM <= EXTMEM,
|
||||
GPIO <= GPIO,
|
||||
I2C_ANA_MST <= I2C_ANA_MST,
|
||||
INTERRUPT_CORE0 <= INTERRUPT_CORE0,
|
||||
IO_MUX <= IO_MUX,
|
||||
LEDC <= LEDC,
|
||||
|
@ -41,6 +41,7 @@ crate::peripherals! {
|
||||
GPIO <= GPIO,
|
||||
GPIO_SD <= GPIO_SD,
|
||||
HMAC <= HMAC,
|
||||
I2C_ANA_MST <= I2C_ANA_MST,
|
||||
I2S0 <= I2S0 (I2S0),
|
||||
INTERRUPT_CORE0 <= INTERRUPT_CORE0,
|
||||
IO_MUX <= IO_MUX,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user