Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create safe wrappers for some ROM functions in the rom module #1290

Merged
merged 4 commits into from
Mar 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion esp-hal/ld/esp32c6/rom-functions.x
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
ets_printf = 0x40000028;
ets_update_cpu_frequency = ets_update_cpu_frequency_rom;
PROVIDE(esp_rom_printf = ets_printf);
PROVIDE(cache_invalidate_icache_all = 0x4000064c);
PROVIDE(cache_suspend_icache = 0x40000698);
Expand Down
3 changes: 1 addition & 2 deletions esp-hal/ld/esp32h2/rom-functions.x
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
ets_printf = 0x40000028;
ets_update_cpu_frequency = ets_update_cpu_frequency_rom;
PROVIDE(esp_rom_printf = ets_printf);
PROVIDE(cache_invalidate_icache_all = 0x40000620);
PROVIDE(cache_suspend_icache = 0x4000066c);
Expand Down Expand Up @@ -27,4 +26,4 @@ PROVIDE(esp_rom_md5_final = 0x40000720);
memset = 0x400004a0;
memcpy = 0x400004a4;
memmove = 0x400004a8;
memcmp = 0x400004ac;
memcmp = 0x400004ac;
3 changes: 2 additions & 1 deletion esp-hal/ld/esp32s3/rom-functions.x
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ PROVIDE(Cache_Resume_DCache = 0x400018c0 );
PROVIDE(rom_config_data_cache_mode = 0x40001a28 );
PROVIDE(rom_config_instruction_cache_mode = 0x40001a1c );
PROVIDE(ets_efuse_get_wp_pad = 0x40001fa4);
PROVIDE(ets_set_appcpu_boot_addr = 0x40000720);

PROVIDE(esp_rom_crc32_be = 0x40001ca4);
PROVIDE(esp_rom_crc16_be = 0x40001cbc);
Expand All @@ -38,4 +39,4 @@ PROVIDE( esp_rom_opiflash_pin_config = 0x40000894 );
memset = 0x400011e8;
memcpy = 0x400011f4;
memmove = 0x40001200;
memcmp = 0x4000120c;
memcmp = 0x4000120c;
7 changes: 1 addition & 6 deletions esp-hal/src/analog/adc/riscv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -590,12 +590,7 @@ where
// the delay might be a bit generous but longer delay seem to not cause problems
#[cfg(esp32c6)]
{
extern "C" {
fn ets_delay_us(us: u32);
}
unsafe {
ets_delay_us(40);
}
crate::rom::ets_delay_us(40);
ADCI::start_onetime_sample();
}
}
Expand Down
280 changes: 105 additions & 175 deletions esp-hal/src/clock/clocks_ll/esp32.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use crate::clock::{Clock, PllClock, XtalClock};
use crate::{
clock::{Clock, PllClock, XtalClock},
regi2c_write,
};

const REF_CLK_FREQ: u32 = 1000000;

Expand Down Expand Up @@ -42,148 +45,108 @@ pub(crate) fn esp32_rtc_bbpll_configure(xtal_freq: XtalClock, pll_freq: PllClock
let efuse = unsafe { &*crate::peripherals::EFUSE::ptr() };
let rtc_cntl = unsafe { &*crate::peripherals::RTC_CNTL::ptr() };

unsafe {
let rtc_cntl_dbias_hp_volt: u32 =
RTC_CNTL_DBIAS_1V25 - efuse.blk0_rdata5().read().rd_vol_level_hp_inv().bits() as u32;
let dig_dbias_240_m: u32 = rtc_cntl_dbias_hp_volt;
let rtc_cntl_dbias_hp_volt: u32 =
RTC_CNTL_DBIAS_1V25 - efuse.blk0_rdata5().read().rd_vol_level_hp_inv().bits() as u32;
let dig_dbias_240_m: u32 = rtc_cntl_dbias_hp_volt;

let div_ref: u32;
let div7_0: u32;
let div10_8: u32;
let lref: u32;
let dcur: u32;
let bw: u32;

if matches!(pll_freq, PllClock::Pll320MHz) {
// Raise the voltage, if needed
rtc_cntl
.reg()
.modify(|_, w| w.dig_dbias_wak().variant(DIG_DBIAS_80M_160M as u8));

// Configure 320M PLL
match xtal_freq {
XtalClock::RtcXtalFreq40M => {
div_ref = 0;
div7_0 = 32;
div10_8 = 0;
lref = 0;
dcur = 6;
bw = 3;
}

XtalClock::RtcXtalFreq26M => {
div_ref = 12;
div7_0 = 224;
div10_8 = 4;
lref = 1;
dcur = 0;
bw = 1;
}

XtalClock::RtcXtalFreqOther(_) => {
div_ref = 12;
div7_0 = 224;
div10_8 = 4;
lref = 0;
dcur = 0;
bw = 0;
}
let div_ref: u32;
let div7_0: u32;
let div10_8: u32;
let lref: u32;
let dcur: u32;
let bw: u32;

if matches!(pll_freq, PllClock::Pll320MHz) {
// Raise the voltage, if needed
rtc_cntl
.reg()
.modify(|_, w| w.dig_dbias_wak().variant(DIG_DBIAS_80M_160M as u8));

// Configure 320M PLL
match xtal_freq {
XtalClock::RtcXtalFreq40M => {
div_ref = 0;
div7_0 = 32;
div10_8 = 0;
lref = 0;
dcur = 6;
bw = 3;
}

i2c_writereg_rtc(
I2C_BBPLL,
I2C_BBPLL_HOSTID,
I2C_BBPLL_ENDIV5,
BBPLL_ENDIV5_VAL_320M,
);
i2c_writereg_rtc(
I2C_BBPLL,
I2C_BBPLL_HOSTID,
I2C_BBPLL_BBADC_DSMP,
BBPLL_BBADC_DSMP_VAL_320M,
);
} else {
// Raise the voltage
rtc_cntl
.reg()
.modify(|_, w| w.dig_dbias_wak().variant(dig_dbias_240_m as u8));

// Configure 480M PLL
match xtal_freq {
XtalClock::RtcXtalFreq40M => {
div_ref = 0;
div7_0 = 28;
div10_8 = 0;
lref = 0;
dcur = 6;
bw = 3;
}

XtalClock::RtcXtalFreq26M => {
div_ref = 12;
div7_0 = 144;
div10_8 = 4;
lref = 1;
dcur = 0;
bw = 1;
}

XtalClock::RtcXtalFreqOther(_) => {
div_ref = 12;
div7_0 = 224;
div10_8 = 4;
lref = 0;
dcur = 0;
bw = 0;
}
XtalClock::RtcXtalFreq26M => {
div_ref = 12;
div7_0 = 224;
div10_8 = 4;
lref = 1;
dcur = 0;
bw = 1;
}

i2c_writereg_rtc(
I2C_BBPLL,
I2C_BBPLL_HOSTID,
I2C_BBPLL_ENDIV5,
BBPLL_ENDIV5_VAL_480M,
);

i2c_writereg_rtc(
I2C_BBPLL,
I2C_BBPLL_HOSTID,
I2C_BBPLL_BBADC_DSMP,
BBPLL_BBADC_DSMP_VAL_480M,
);
XtalClock::RtcXtalFreqOther(_) => {
div_ref = 12;
div7_0 = 224;
div10_8 = 4;
lref = 0;
dcur = 0;
bw = 0;
}
}

let i2c_bbpll_lref = (lref << 7) | (div10_8 << 4) | (div_ref);
let i2c_bbpll_div_7_0 = div7_0;
let i2c_bbpll_dcur = (bw << 6) | dcur;
i2c_writereg_rtc(
I2C_BBPLL,
I2C_BBPLL_HOSTID,
I2C_BBPLL_OC_LREF,
i2c_bbpll_lref,
);

i2c_writereg_rtc(
I2C_BBPLL,
I2C_BBPLL_HOSTID,
I2C_BBPLL_OC_DIV_7_0,
i2c_bbpll_div_7_0,
);

i2c_writereg_rtc(
I2C_BBPLL,
I2C_BBPLL_HOSTID,
I2C_BBPLL_OC_DCUR,
i2c_bbpll_dcur,
);
regi2c_write!(I2C_BBPLL, I2C_BBPLL_ENDIV5, BBPLL_ENDIV5_VAL_320M);
regi2c_write!(I2C_BBPLL, I2C_BBPLL_BBADC_DSMP, BBPLL_BBADC_DSMP_VAL_320M);
} else {
// Raise the voltage
rtc_cntl
.reg()
.modify(|_, w| w.dig_dbias_wak().variant(dig_dbias_240_m as u8));

// Configure 480M PLL
match xtal_freq {
XtalClock::RtcXtalFreq40M => {
div_ref = 0;
div7_0 = 28;
div10_8 = 0;
lref = 0;
dcur = 6;
bw = 3;
}

XtalClock::RtcXtalFreq26M => {
div_ref = 12;
div7_0 = 144;
div10_8 = 4;
lref = 1;
dcur = 0;
bw = 1;
}

XtalClock::RtcXtalFreqOther(_) => {
div_ref = 12;
div7_0 = 224;
div10_8 = 4;
lref = 0;
dcur = 0;
bw = 0;
}
}

regi2c_write!(I2C_BBPLL, I2C_BBPLL_ENDIV5, BBPLL_ENDIV5_VAL_480M);
regi2c_write!(I2C_BBPLL, I2C_BBPLL_BBADC_DSMP, BBPLL_BBADC_DSMP_VAL_480M);
}

let i2c_bbpll_lref = (lref << 7) | (div10_8 << 4) | (div_ref);
let i2c_bbpll_div_7_0 = div7_0;
let i2c_bbpll_dcur = (bw << 6) | dcur;

regi2c_write!(I2C_BBPLL, I2C_BBPLL_OC_LREF, i2c_bbpll_lref);
regi2c_write!(I2C_BBPLL, I2C_BBPLL_OC_DIV_7_0, i2c_bbpll_div_7_0);
regi2c_write!(I2C_BBPLL, I2C_BBPLL_OC_DCUR, i2c_bbpll_dcur);
}

pub(crate) fn esp32_rtc_bbpll_enable() {
let rtc_cntl = unsafe { &*crate::peripherals::RTC_CNTL::ptr() };

unsafe {
rtc_cntl.options0().modify(|_, w| {
unsafe { &*crate::peripherals::RTC_CNTL::ptr() }
.options0()
.modify(|_, w| {
w.bias_i2c_force_pd()
.clear_bit()
.bb_i2c_force_pd()
Expand All @@ -194,49 +157,16 @@ pub(crate) fn esp32_rtc_bbpll_enable() {
.clear_bit()
});

// reset BBPLL configuration
i2c_writereg_rtc(
I2C_BBPLL,
I2C_BBPLL_HOSTID,
I2C_BBPLL_IR_CAL_DELAY,
BBPLL_IR_CAL_DELAY_VAL,
);
i2c_writereg_rtc(
I2C_BBPLL,
I2C_BBPLL_HOSTID,
I2C_BBPLL_IR_CAL_EXT_CAP,
BBPLL_IR_CAL_EXT_CAP_VAL,
);
i2c_writereg_rtc(
I2C_BBPLL,
I2C_BBPLL_HOSTID,
I2C_BBPLL_OC_ENB_FCAL,
BBPLL_OC_ENB_FCAL_VAL,
);
i2c_writereg_rtc(
I2C_BBPLL,
I2C_BBPLL_HOSTID,
I2C_BBPLL_OC_ENB_VCON,
BBPLL_OC_ENB_VCON_VAL,
);
i2c_writereg_rtc(
I2C_BBPLL,
I2C_BBPLL_HOSTID,
I2C_BBPLL_BBADC_CAL_7_0,
BBPLL_BBADC_CAL_7_0_VAL,
);
}
}

#[inline(always)]
unsafe fn i2c_writereg_rtc(block: u32, block_hostid: u32, reg_add: u32, indata: u32) {
const ROM_I2C_WRITEREG: u32 = 0x400041a4;

// cast to usize is just needed because of the way we run clippy in CI
let rom_i2c_writereg: fn(block: u32, block_hostid: u32, reg_add: u32, indata: u32) -> i32 =
core::mem::transmute(ROM_I2C_WRITEREG as usize);

rom_i2c_writereg(block, block_hostid, reg_add, indata);
// reset BBPLL configuration
regi2c_write!(I2C_BBPLL, I2C_BBPLL_IR_CAL_DELAY, BBPLL_IR_CAL_DELAY_VAL);
regi2c_write!(
I2C_BBPLL,
I2C_BBPLL_IR_CAL_EXT_CAP,
BBPLL_IR_CAL_EXT_CAP_VAL
);
regi2c_write!(I2C_BBPLL, I2C_BBPLL_OC_ENB_FCAL, BBPLL_OC_ENB_FCAL_VAL);
regi2c_write!(I2C_BBPLL, I2C_BBPLL_OC_ENB_VCON, BBPLL_OC_ENB_VCON_VAL);
regi2c_write!(I2C_BBPLL, I2C_BBPLL_BBADC_CAL_7_0, BBPLL_BBADC_CAL_7_0_VAL);
}

pub(crate) fn esp32_rtc_update_to_xtal(freq: XtalClock, _div: u32) {
Expand Down
11 changes: 4 additions & 7 deletions esp-hal/src/clock/clocks_ll/esp32c2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ use crate::{
regi2c_write_mask,
};

extern "C" {
fn ets_update_cpu_frequency_rom(ticks_per_us: u32);
}

const I2C_BBPLL: u32 = 0x66;
const I2C_BBPLL_HOSTID: u32 = 0;

Expand Down Expand Up @@ -123,10 +119,10 @@ pub(crate) fn esp32c2_rtc_bbpll_enable() {
}

pub(crate) fn esp32c2_rtc_update_to_xtal(freq: XtalClock, _div: u32) {
let system_control = unsafe { &*crate::peripherals::SYSTEM::ptr() };
crate::rom::ets_update_cpu_frequency_rom(freq.mhz());

let system_control = unsafe { &*crate::peripherals::SYSTEM::ptr() };
unsafe {
ets_update_cpu_frequency_rom(freq.mhz());
// Set divider from XTAL to APB clock. Need to set divider to 1 (reg. value 0)
// first.
system_control.sysclk_conf().modify(|_, w| {
Expand Down Expand Up @@ -158,8 +154,9 @@ pub(crate) fn esp32c2_rtc_freq_to_pll_mhz(cpu_clock_speed: CpuClock) {
CpuClock::Clock120MHz => 1,
})
});
ets_update_cpu_frequency_rom(cpu_clock_speed.mhz());
}

crate::rom::ets_update_cpu_frequency_rom(cpu_clock_speed.mhz());
}

pub(crate) fn esp32c2_rtc_apb_freq_update(apb_freq: ApbClock) {
Expand Down
Loading
Loading