Skip to content

Commit

Permalink
Refactor the clock module, provide ROM functions via linker scripts (
Browse files Browse the repository at this point in the history
…#353)

* Refactor `clock` and `clocks_ll` into a common module

* Add a ROM function linker script to each HAL and provide some functions

* Use the provided ROM functions instead of transmuting addresses

* Fix CI workflow for ESP32-S2
  • Loading branch information
jessebraham authored Jan 23, 2023
1 parent 1ec6f98 commit 832f9ef
Show file tree
Hide file tree
Showing 27 changed files with 110 additions and 146 deletions.
3 changes: 0 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,6 @@ jobs:
esp32s2-hal:
runs-on: ubuntu-latest

env:
RUSTFLAGS: '--cfg target_has_atomic="8" --cfg target_has_atomic="16" --cfg target_has_atomic="32" --cfg target_has_atomic="ptr"'

steps:
- uses: actions/checkout@v2
- uses: esp-rs/[email protected]
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@ use crate::{
clock::{ApbClock, Clock, CpuClock, PllClock, XtalClock},
regi2c_write,
regi2c_write_mask,
rom::{ets_update_cpu_frequency, regi2c_ctrl_write_reg, regi2c_ctrl_write_reg_mask},
rom::{rom_i2c_writeReg, rom_i2c_writeReg_Mask},
};

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

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@ use crate::{
clock::{ApbClock, Clock, CpuClock, PllClock, XtalClock},
regi2c_write,
regi2c_write_mask,
rom::{ets_update_cpu_frequency, regi2c_ctrl_write_reg, regi2c_ctrl_write_reg_mask},
rom::{rom_i2c_writeReg, rom_i2c_writeReg_Mask},
};

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

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

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
138 changes: 17 additions & 121 deletions esp-hal-common/src/rom.rs
Original file line number Diff line number Diff line change
@@ -1,147 +1,43 @@
pub use paste::paste;

/// Pauses execution for us microseconds
#[inline(always)]
pub unsafe fn esp_rom_delay_us(us: u32) {
#[cfg(esp32)]
const ESP_ROM_DELAY_US: u32 = 0x4000_8534;
#[cfg(esp32c2)]
const ESP_ROM_DELAY_US: u32 = 0x4000_0044;
#[cfg(esp32c3)]
const ESP_ROM_DELAY_US: u32 = 0x4000_0050;
#[cfg(esp32s2)]
const ESP_ROM_DELAY_US: u32 = 0x4000_d888;
#[cfg(esp32s3)]
const ESP_ROM_DELAY_US: u32 = 0x4000_0600;
#[allow(unused)]
extern "C" {
pub(crate) fn rom_i2c_writeReg(block: u32, block_hostid: u32, reg_add: u32, indata: u32);

// cast to usize is just needed because of the way we run clippy in CI
let fn_esp_rom_delay_us: fn(us: u32) = core::mem::transmute(ESP_ROM_DELAY_US as usize);

fn_esp_rom_delay_us(us);
}

#[inline(always)]
/// Set the real CPU ticks per us to the ets, so that ets_delay_us
/// will be accurate. Call this function when CPU frequency is changed.
pub unsafe fn ets_update_cpu_frequency(ticks_per_us: u32) {
#[cfg(esp32)]
const ETS_UPDATE_CPU_FREQUENCY: u32 = 0x4000_8550;
#[cfg(esp32c2)]
const ETS_UPDATE_CPU_FREQUENCY: u32 = 0x4000_0774;
#[cfg(esp32c3)]
const ETS_UPDATE_CPU_FREQUENCY: u32 = 0x4000_0588;
#[cfg(esp32s2)]
const ETS_UPDATE_CPU_FREQUENCY: u32 = 0x4000_d8a4;
#[cfg(esp32s3)]
const ETS_UPDATE_CPU_FREQUENCY: u32 = 0x4004_3164;

// cast to usize is just needed because of the way we run clippy in CI
let rom_ets_update_cpu_frequency: fn(ticks_per_us: u32) =
core::mem::transmute(ETS_UPDATE_CPU_FREQUENCY as usize);

rom_ets_update_cpu_frequency(ticks_per_us);
}

#[inline(always)]
pub unsafe fn regi2c_ctrl_write_reg(block: u32, block_hostid: u32, reg_add: u32, indata: u32) {
#[cfg(esp32)]
const ROM_I2C_WRITEREG: u32 = 0x4000_41a4;
#[cfg(esp32c2)]
const ROM_I2C_WRITEREG: u32 = 0x4000_22f4;
#[cfg(esp32c3)]
const ROM_I2C_WRITEREG: u32 = 0x4000_195c;
#[cfg(esp32s2)]
const ROM_I2C_WRITEREG: u32 = 0x4000_a9a8;
#[cfg(esp32s3)]
const ROM_I2C_WRITEREG: u32 = 0x4000_5d60;

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

i2c_write_reg_raw(block, block_hostid, reg_add, indata);
pub(crate) fn rom_i2c_writeReg_Mask(
block: u32,
block_hostid: u32,
reg_add: u32,
reg_add_msb: u32,
reg_add_lsb: u32,
indata: u32,
);
}

#[macro_export]
macro_rules! regi2c_write {
( $block: ident, $reg_add: ident, $indata: expr ) => {
paste! {
regi2c_ctrl_write_reg($block,
rom_i2c_writeReg($block,
[<$block _HOSTID>],
$reg_add,
$indata);
$indata
);
}
};
}

#[inline(always)]
pub unsafe fn regi2c_ctrl_write_reg_mask(
block: u32,
block_hostid: u32,
reg_add: u32,
reg_add_msb: u32,
reg_add_lsb: u32,
indata: u32,
) {
#[cfg(esp32)]
const ROM_I2C_WRITEREG_MASK: u32 = 0x4000_41fc;
#[cfg(esp32c2)]
const ROM_I2C_WRITEREG_MASK: u32 = 0x4000_22fc;
#[cfg(esp32c3)]
const ROM_I2C_WRITEREG_MASK: u32 = 0x4000_1960;
#[cfg(esp32s2)]
const ROM_I2C_WRITEREG_MASK: u32 = 0x4000_aa00;
#[cfg(esp32s3)]
const ROM_I2C_WRITEREG_MASK: u32 = 0x4000_5d6c;

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

i2c_write_reg_mask_raw(
block,
block_hostid,
reg_add,
reg_add_msb,
reg_add_lsb,
indata,
);
}

#[macro_export]
macro_rules! regi2c_write_mask {
( $block: ident, $reg_add: ident, $indata: expr ) => {
paste! {
regi2c_ctrl_write_reg_mask($block,
rom_i2c_writeReg_Mask($block,
[<$block _HOSTID>],
$reg_add,
[<$reg_add _MSB>],
[<$reg_add _LSB>],
$indata);
$indata
);
}
};
}

/// Determine the reason that the specified CPU reset
pub unsafe fn rtc_get_reset_reason(cpu_num: u32) -> u32 {
#[cfg(esp32)]
const RTC_GET_RESET_REASON: u32 = 0x4000_81d4;
#[cfg(esp32c2)]
const RTC_GET_RESET_REASON: u32 = 0x4000_0018;
#[cfg(esp32c3)]
const RTC_GET_RESET_REASON: u32 = 0x4000_0018;
#[cfg(esp32s2)]
const RTC_GET_RESET_REASON: u32 = 0x4000_ff58;
#[cfg(esp32s3)]
const RTC_GET_RESET_REASON: u32 = 0x4000_057c;

let get_reason: fn(u32) -> u32 = core::mem::transmute(RTC_GET_RESET_REASON as usize);

get_reason(cpu_num)
}
19 changes: 12 additions & 7 deletions esp-hal-common/src/rtc_cntl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ use crate::{
clock::{Clock, XtalClock},
peripheral::{Peripheral, PeripheralRef},
peripherals::{RTC_CNTL, TIMG0},
rom::esp_rom_delay_us,
Cpu,
};

Expand All @@ -19,6 +18,12 @@ use crate::{
#[cfg_attr(esp32s3, path = "rtc/esp32s3.rs")]
mod rtc;

extern "C" {
fn ets_delay_us(us: u32);

fn rtc_get_reset_reason(cpu_num: u32) -> u32;
}

#[allow(unused)]
#[derive(Debug, Clone, Copy)]
/// RTC SLOW_CLK frequency values
Expand Down Expand Up @@ -137,7 +142,7 @@ impl RtcClock {
rtc_cntl.clk_conf.modify(|_, w| w.enb_ck8m().clear_bit());
unsafe {
rtc_cntl.timer1.modify(|_, w| w.ck8m_wait().bits(5));
esp_rom_delay_us(50);
ets_delay_us(50);
}
} else {
rtc_cntl.clk_conf.modify(|_, w| w.enb_ck8m().set_bit());
Expand Down Expand Up @@ -222,7 +227,7 @@ impl RtcClock {
})
});

esp_rom_delay_us(300u32);
ets_delay_us(300u32);
};
}

Expand All @@ -237,7 +242,7 @@ impl RtcClock {
})
});

esp_rom_delay_us(3u32);
ets_delay_us(3u32);
};
}

Expand Down Expand Up @@ -343,7 +348,7 @@ impl RtcClock {

// Wait for calibration to finish up to another us_time_estimate
unsafe {
esp_rom_delay_us(us_time_estimate);
ets_delay_us(us_time_estimate);
}

#[cfg(esp32)]
Expand All @@ -364,7 +369,7 @@ impl RtcClock {
if timeout_us > 0 {
timeout_us -= 1;
unsafe {
esp_rom_delay_us(1);
ets_delay_us(1);
}
} else {
// Timed out waiting for calibration
Expand Down Expand Up @@ -670,7 +675,7 @@ impl WatchdogDisable for Swd {
}

pub fn get_reset_reason(cpu: Cpu) -> Option<SocResetReason> {
let reason = unsafe { crate::rom::rtc_get_reset_reason(cpu as u32) };
let reason = unsafe { rtc_get_reset_reason(cpu as u32) };
let reason = SocResetReason::from_repr(reason as usize);

reason
Expand Down
2 changes: 1 addition & 1 deletion esp-hal-common/src/rtc_cntl/rtc/esp32c2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
clock::XtalClock,
peripherals::{APB_CTRL, EXTMEM, RTC_CNTL, SPI0, SPI1, SYSTEM},
regi2c_write_mask,
rom::regi2c_ctrl_write_reg_mask,
rom::rom_i2c_writeReg_Mask,
rtc_cntl::{RtcCalSel, RtcClock, RtcFastClock, RtcSlowClock},
};

Expand Down
2 changes: 1 addition & 1 deletion esp-hal-common/src/rtc_cntl/rtc/esp32c3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
clock::XtalClock,
peripherals::{APB_CTRL, EXTMEM, RTC_CNTL, SPI0, SPI1, SYSTEM},
regi2c_write_mask,
rom::regi2c_ctrl_write_reg_mask,
rom::rom_i2c_writeReg_Mask,
rtc_cntl::{RtcCalSel, RtcClock, RtcFastClock, RtcSlowClock},
};

Expand Down
5 changes: 5 additions & 0 deletions esp32-hal/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ fn main() {
.write_all(include_bytes!("ld/hal-defaults.x"))
.unwrap();

File::create(out.join("rom-functions.x"))
.unwrap()
.write_all(include_bytes!("ld/rom-functions.x"))
.unwrap();

File::create(out.join("linkall.x"))
.unwrap()
.write_all(include_bytes!("ld/linkall.x"))
Expand Down
1 change: 1 addition & 0 deletions esp32-hal/ld/linkall.x
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
INCLUDE "link-esp32.x"
INCLUDE "hal-defaults.x"
INCLUDE "rom-functions.x"
5 changes: 5 additions & 0 deletions esp32-hal/ld/rom-functions.x
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
PROVIDE(ets_delay_us = 0x40008534);
PROVIDE(ets_update_cpu_frequency_rom = 0x40008550);
PROVIDE(rom_i2c_writeReg = 0x400041a4);
PROVIDE(rom_i2c_writeReg_Mask = 0x400041fc);
PROVIDE(rtc_get_reset_reason = 0x400081d4);
6 changes: 6 additions & 0 deletions esp32c2-hal/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,16 @@ fn check_features() {

fn add_defaults() {
let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());

File::create(out.join("hal-defaults.x"))
.unwrap()
.write_all(include_bytes!("ld/hal-defaults.x"))
.unwrap();

File::create(out.join("rom-functions.x"))
.unwrap()
.write_all(include_bytes!("ld/rom-functions.x"))
.unwrap();

println!("cargo:rustc-link-search={}", out.display());
}
1 change: 1 addition & 0 deletions esp32c2-hal/ld/bl-linkall.x
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
INCLUDE "memory.x"
INCLUDE "bl-riscv-link.x"
INCLUDE "hal-defaults.x"
INCLUDE "rom-functions.x"
1 change: 1 addition & 0 deletions esp32c2-hal/ld/db-linkall.x
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
INCLUDE "esp32c2-link.x"
INCLUDE "hal-defaults.x"
INCLUDE "rom-functions.x"
5 changes: 5 additions & 0 deletions esp32c2-hal/ld/rom-functions.x
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
PROVIDE(ets_delay_us = 0x40000044);
PROVIDE(ets_update_cpu_frequency_rom = 0x40008550);
PROVIDE(rom_i2c_writeReg = 0x400022f4);
PROVIDE(rom_i2c_writeReg_Mask = 0x400022fc);
PROVIDE(rtc_get_reset_reason = 0x40000018);
1 change: 1 addition & 0 deletions esp32c3-hal/ld/bl-linkall.x
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
INCLUDE "memory.x"
INCLUDE "bl-riscv-link.x"
INCLUDE "hal-defaults.x"
INCLUDE "rom-functions.x"
3 changes: 2 additions & 1 deletion esp32c3-hal/ld/db-linkall.x
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
INCLUDE "esp32c3-link.x"
INCLUDE "hal-defaults.x"
INCLUDE "hal-defaults.x"
INCLUDE "rom-functions.x"
5 changes: 5 additions & 0 deletions esp32c3-hal/ld/rom-functions.x
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,8 @@ PROVIDE(cache_suspend_icache = 0x40000524);
PROVIDE(cache_resume_icache = 0x40000528);
PROVIDE(cache_ibus_mmu_set = 0x40000560);
PROVIDE(cache_dbus_mmu_set = 0x40000564);
PROVIDE(ets_delay_us = 0x40000050);
PROVIDE(ets_update_cpu_frequency_rom = 0x40000588);
PROVIDE(rom_i2c_writeReg = 0x4000195c);
PROVIDE(rom_i2c_writeReg_Mask = 0x40001960);
PROVIDE(rtc_get_reset_reason = 0x40000018);
5 changes: 5 additions & 0 deletions esp32s2-hal/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ fn main() {
.write_all(include_bytes!("ld/hal-defaults.x"))
.unwrap();

File::create(out.join("rom-functions.x"))
.unwrap()
.write_all(include_bytes!("ld/rom-functions.x"))
.unwrap();

File::create(out.join("linkall.x"))
.unwrap()
.write_all(include_bytes!("ld/linkall.x"))
Expand Down
1 change: 1 addition & 0 deletions esp32s2-hal/ld/linkall.x
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
INCLUDE "link-esp32s2.x"
INCLUDE "hal-defaults.x"
INCLUDE "rom-functions.x"
5 changes: 5 additions & 0 deletions esp32s2-hal/ld/rom-functions.x
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
PROVIDE(ets_delay_us = 0x4000d888);
PROVIDE(ets_update_cpu_frequency_rom = 0x4000d8a4);
PROVIDE(rom_i2c_writeReg = 0x4000a9a8);
PROVIDE(rom_i2c_writeReg_Mask = 0x4000aa00);
PROVIDE(rtc_get_reset_reason = 0x4000ff58);
Loading

0 comments on commit 832f9ef

Please sign in to comment.