Skip to content

Commit e61f99f

Browse files
committed
RISC-V peripheral rework
1 parent 67ff241 commit e61f99f

File tree

9 files changed

+78
-24
lines changed

9 files changed

+78
-24
lines changed

e310x-hal/src/clock.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Clock configuration
22
use crate::time::Hertz;
3-
use e310x::{Aonclk as AONCLK, Prci as PRCI, CLINT};
3+
use e310x::{Aonclk as AONCLK, Clint, Prci as PRCI};
44
use riscv::interrupt;
55
use riscv::register::mcycle;
66

@@ -290,7 +290,7 @@ impl CoreClk {
290290
// Need to wait 100 us
291291
// RTC is running at 32kHz.
292292
// So wait 4 ticks of RTC.
293-
let mtime = CLINT::mtimer().mtime;
293+
let mtime = unsafe { Clint::steal() }.mtimer().mtime();
294294
let time = mtime.read() + 4;
295295
while mtime.read() < time {}
296296
// Now it is safe to check for PLL Lock
@@ -384,7 +384,7 @@ impl Clocks {
384384

385385
/// Measure the coreclk frequency by counting the number of aonclk ticks.
386386
fn _measure_coreclk(&self, min_ticks: u64) -> Hertz {
387-
let mtime = CLINT::mtimer().mtime;
387+
let mtime = unsafe { Clint::steal() }.mtimer().mtime();
388388
interrupt::free(|| {
389389
// Don't start measuring until we see an mtime tick
390390
while mtime.read() == mtime.read() {}

e310x-hal/src/core/counters.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ pub struct PerformanceCounters {
6060
}
6161

6262
impl PerformanceCounters {
63-
pub(crate) fn new() -> Self {
63+
pub(crate) const fn new() -> Self {
6464
Self {
6565
mcycle: MCYCLE,
6666
minstret: MINSTRET,

e310x-hal/src/core/mod.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,23 @@
22
33
pub mod counters;
44

5-
pub use e310x::{CLINT, PLIC};
5+
use e310x::{Clint, Plic};
66

77
/// Core peripherals
88
pub struct CorePeripherals {
9+
/// Core Local Interruptor (CLINT)
10+
pub clint: Clint,
11+
/// Platform-Level Interrupt Controller (PLIC)
12+
pub plic: Plic,
913
/// Performance counters
1014
pub counters: counters::PerformanceCounters,
1115
}
1216

1317
impl CorePeripherals {
14-
pub(crate) fn new() -> Self {
18+
pub(crate) const fn new(clint: Clint, plic: Plic) -> Self {
1519
Self {
20+
clint,
21+
plic,
1622
counters: counters::PerformanceCounters::new(),
1723
}
1824
}
@@ -23,6 +29,6 @@ impl CorePeripherals {
2329
///
2430
/// Using this function may break the guarantees of the singleton pattern.
2531
pub unsafe fn steal() -> Self {
26-
Self::new()
32+
Self::new(Clint::steal(), Plic::steal())
2733
}
2834
}

e310x-hal/src/delay.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! # Delays
22
33
use crate::clock::Clocks;
4-
use e310x::CLINT;
4+
use e310x::Clint;
55
use embedded_hal::delay::DelayNs;
66
use riscv::register::mip;
77

@@ -22,7 +22,7 @@ impl DelayNs for Delay {
2222
fn delay_ns(&mut self, ns: u32) {
2323
let ticks = (ns as u64) * TICKS_PER_SECOND / 1_000_000_000;
2424

25-
let mtime = CLINT::mtimer().mtime;
25+
let mtime = unsafe { Clint::steal() }.mtimer().mtime();
2626
let t = mtime.read() + ticks;
2727
while mtime.read() < t {}
2828
}
@@ -45,12 +45,13 @@ impl Sleep {
4545
impl DelayNs for Sleep {
4646
fn delay_ns(&mut self, ns: u32) {
4747
let ticks = (ns as u64) * u64::from(self.clock_freq) / 1_000_000_000;
48-
let t = CLINT::mtimer().mtime.read() + ticks;
48+
let clint = unsafe { e310x::Clint::steal() };
49+
let t = clint.mtimer().mtime().read() + ticks;
4950

50-
CLINT::mtimecmp0().write(t);
51+
clint.mtimecmp0().write(t);
5152

5253
// Enable timer interrupt
53-
unsafe { CLINT::mtimer_enable() };
54+
unsafe { clint.mtimer().enable() };
5455

5556
// Wait For Interrupt will put CPU to sleep until an interrupt hits
5657
// in our case when internal timer mtime value >= mtimecmp value
@@ -66,6 +67,6 @@ impl DelayNs for Sleep {
6667
}
6768

6869
// Clear timer interrupt
69-
CLINT::mtimer_disable();
70+
clint.mtimer().disable();
7071
}
7172
}

e310x-hal/src/device.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ impl From<Peripherals> for DeviceResources {
159159
};
160160

161161
DeviceResources {
162-
core_peripherals: CorePeripherals::new(),
162+
core_peripherals: CorePeripherals::new(p.clint, p.plic),
163163
peripherals,
164164
pins: p.gpio0.into(),
165165
}

e310x/Cargo.toml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,12 @@ edition = "2021"
1212

1313
[dependencies]
1414
critical-section = { version = "1.2.0", optional = true }
15-
riscv = "0.13.0"
16-
riscv-peripheral = "0.2.0"
17-
riscv-rt = { version = "0.14.0", features = ["no-interrupts"], optional = true }
15+
riscv = { git = "https://github.com/rust-embedded/riscv.git", branch = "riscv-peripheral-rework" }
16+
riscv-peripheral = { git = "https://github.com/rust-embedded/riscv.git", branch = "riscv-peripheral-rework" }
17+
riscv-rt = { git = "https://github.com/rust-embedded/riscv.git", branch = "riscv-peripheral-rework", features = ["no-interrupts"], optional = true }
18+
# riscv = "0.13.0"
19+
# riscv-peripheral = "0.2.0"
20+
# riscv-rt = { version = "0.14.0", features = ["no-interrupts"], optional = true }
1821
vcell = "0.1.3"
1922

2023
[features]

e310x/settings.yaml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,7 @@ riscv_config:
4343

4444
clint:
4545
name: "CLINT"
46-
freq: 32768
47-
async_delay: false
46+
mtime_freq: 32768
4847

4948
plic:
5049
name: "PLIC"

e310x/src/interrupt.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,9 @@ pub enum ExternalInterrupt {
168168
}
169169
#[cfg(feature = "rt")]
170170
#[riscv_rt::core_interrupt(CoreInterrupt::MachineExternal)]
171-
fn plic_handler() {
172-
let claim = crate::PLIC::ctx(Hart::H0).claim();
171+
unsafe fn plic_handler() {
172+
let plic = unsafe { crate::Plic::steal() };
173+
let claim = plic.ctx(Hart::H0).claim();
173174
if let Some(s) = claim.claim::<ExternalInterrupt>() {
174175
unsafe { _dispatch_external_interrupt(s.number()) }
175176
claim.complete(s);

e310x/src/lib.rs

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#![doc = "Peripheral access API for FE310 microcontrollers (generated using svd2rust v0.36.1 ( ))\n\nYou can find an overview of the generated API [here].\n\nAPI features to be included in the [next] svd2rust release can be generated by cloning the svd2rust [repository], checking out the above commit, and running `cargo doc --open`.\n\n[here]: https://docs.rs/svd2rust/0.36.1/svd2rust/#peripheral-api\n[next]: https://github.com/rust-embedded/svd2rust/blob/master/CHANGELOG.md#unreleased\n[repository]: https://github.com/rust-embedded/svd2rust"]
1+
#![doc = "Peripheral access API for FE310 microcontrollers (generated using svd2rust v0.36.1 (7a01f7c 2025-05-24))\n\nYou can find an overview of the generated API [here].\n\nAPI features to be included in the [next] svd2rust release can be generated by cloning the svd2rust [repository], checking out the above commit, and running `cargo doc --open`.\n\n[here]: https://docs.rs/svd2rust/0.36.1/svd2rust/#peripheral-api\n[next]: https://github.com/rust-embedded/svd2rust/blob/master/CHANGELOG.md#unreleased\n[repository]: https://github.com/rust-embedded/svd2rust"]
22
#![allow(non_camel_case_types)]
33
#![allow(non_snake_case)]
44
#![no_std]
@@ -9,8 +9,46 @@ use generic::*;
99
pub mod generic;
1010
#[doc = r" Interrupt numbers, priority levels, and HART IDs."]
1111
pub mod interrupt;
12-
riscv_peripheral :: clint_codegen ! (base 0x2000000 , freq 32768 , mtimecmps [mtimecmp0 = (crate :: interrupt :: Hart :: H0 , "[0](crate::interrupt::Hart::H0)")] , msips [msip0 = (crate :: interrupt :: Hart :: H0 , "[0](crate::interrupt::Hart::H0)")] ,);
13-
riscv_peripheral :: plic_codegen ! (base 0xC000000 , ctxs [ctx0 = (crate :: interrupt :: Hart :: H0 , "[0](crate::interrupt::Hart::H0)")] ,);
12+
riscv_peripheral :: clint_codegen ! (Clint , base 0x2000000 , mtime_freq 32768 , harts [crate :: interrupt :: Hart :: H0 => 0]);
13+
impl Clint {
14+
#[doc = r" Steal an instance of this peripheral"]
15+
#[doc = r""]
16+
#[doc = r" # Safety"]
17+
#[doc = r""]
18+
#[doc = r" Ensure that the new instance of the peripheral cannot be used in a way"]
19+
#[doc = r" that may race with any existing instances, for example by only"]
20+
#[doc = r" accessing read-only or write-only registers, or by consuming the"]
21+
#[doc = r" original peripheral and using critical sections to coordinate"]
22+
#[doc = r" access between multiple new instances."]
23+
#[doc = r""]
24+
#[doc = r" Additionally, other software such as HALs may rely on only one"]
25+
#[doc = r" peripheral instance existing to ensure memory safety; ensure"]
26+
#[doc = r" no stolen instances are passed to such software."]
27+
#[inline]
28+
pub unsafe fn steal() -> Self {
29+
Self::new()
30+
}
31+
}
32+
riscv_peripheral :: plic_codegen ! (Plic , base 0xC000000 , harts [crate :: interrupt :: Hart :: H0 => 0]);
33+
impl Plic {
34+
#[doc = r" Steal an instance of this peripheral"]
35+
#[doc = r""]
36+
#[doc = r" # Safety"]
37+
#[doc = r""]
38+
#[doc = r" Ensure that the new instance of the peripheral cannot be used in a way"]
39+
#[doc = r" that may race with any existing instances, for example by only"]
40+
#[doc = r" accessing read-only or write-only registers, or by consuming the"]
41+
#[doc = r" original peripheral and using critical sections to coordinate"]
42+
#[doc = r" access between multiple new instances."]
43+
#[doc = r""]
44+
#[doc = r" Additionally, other software such as HALs may rely on only one"]
45+
#[doc = r" peripheral instance existing to ensure memory safety; ensure"]
46+
#[doc = r" no stolen instances are passed to such software."]
47+
#[inline]
48+
pub unsafe fn steal() -> Self {
49+
Self::new()
50+
}
51+
}
1452
#[doc = "Watchdog"]
1553
pub type Wdog = crate::Periph<wdog::RegisterBlock, 0x1000_0000>;
1654
impl core::fmt::Debug for Wdog {
@@ -172,6 +210,10 @@ static mut DEVICE_PERIPHERALS: bool = false;
172210
#[doc = r" All the peripherals."]
173211
#[allow(non_snake_case)]
174212
pub struct Peripherals {
213+
#[doc = "CLINT"]
214+
pub clint: Clint,
215+
#[doc = "PLIC"]
216+
pub plic: Plic,
175217
#[doc = "WDOG"]
176218
pub wdog: Wdog,
177219
#[doc = "RTC"]
@@ -229,6 +271,8 @@ impl Peripherals {
229271
pub unsafe fn steal() -> Self {
230272
DEVICE_PERIPHERALS = true;
231273
Peripherals {
274+
clint: Clint::steal(),
275+
plic: Plic::steal(),
232276
wdog: Wdog::steal(),
233277
rtc: Rtc::steal(),
234278
aonclk: Aonclk::steal(),

0 commit comments

Comments
 (0)