Skip to content

Commit d972098

Browse files
committed
use generics for peripherals too
1 parent dac8766 commit d972098

File tree

4 files changed

+57
-56
lines changed

4 files changed

+57
-56
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
77

88
## [Unreleased]
99

10+
- Generic `Periph<RB, A>`
1011
- Add `mtvec_align` field to `riscv_config` to configure the byte alignment of interrupt vector table.
1112
- Fix reexport path when "%s" inside "derivedFrom"
1213
- Force using rust edition 2021 in CI

src/generate/device.rs

-5
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,6 @@ pub fn render(d: &Device, config: &Config, device_x: &mut String) -> Result<Toke
6262
});
6363
}
6464

65-
out.extend(quote! {
66-
use core::ops::Deref;
67-
use core::marker::PhantomData;
68-
});
69-
7065
// Retaining the previous assumption
7166
let mut fpu_present = true;
7267

src/generate/generic.rs

+55-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,51 @@
11
use core::marker;
22

3+
/// Generic peripheral accessor
4+
pub struct Periph<RB, const A: usize> {
5+
_marker: marker::PhantomData<RB>,
6+
}
7+
8+
unsafe impl<RB, const A: usize> Send for Periph<RB, A> {}
9+
10+
impl<RB, const A: usize> Periph<RB, A> {
11+
///Pointer to the register block
12+
pub const PTR: *const RB = A as *const _;
13+
14+
///Return the pointer to the register block
15+
#[inline(always)]
16+
pub const fn ptr() -> *const RB {
17+
Self::PTR
18+
}
19+
20+
/// Steal an instance of this peripheral
21+
///
22+
/// # Safety
23+
///
24+
/// Ensure that the new instance of the peripheral cannot be used in a way
25+
/// that may race with any existing instances, for example by only
26+
/// accessing read-only or write-only registers, or by consuming the
27+
/// original peripheral and using critical sections to coordinate
28+
/// access between multiple new instances.
29+
///
30+
/// Additionally, other software such as HALs may rely on only one
31+
/// peripheral instance existing to ensure memory safety; ensure
32+
/// no stolen instances are passed to such software.
33+
pub unsafe fn steal() -> Self {
34+
Self {
35+
_marker: marker::PhantomData,
36+
}
37+
}
38+
}
39+
40+
impl<RB, const A: usize> core::ops::Deref for Periph<RB, A> {
41+
type Target = RB;
42+
43+
#[inline(always)]
44+
fn deref(&self) -> &Self::Target {
45+
unsafe { &*Self::PTR }
46+
}
47+
}
48+
349
/// Raw register type (`u8`, `u16`, `u32`, ...)
450
pub trait RawReg:
551
Copy
@@ -247,7 +293,10 @@ impl<REG: Writable> W<REG> {
247293
self
248294
}
249295
}
250-
impl<REG> W<REG> where REG: Writable<Safety = Safe> {
296+
impl<REG> W<REG>
297+
where
298+
REG: Writable<Safety = Safe>,
299+
{
251300
/// Writes raw bits to the register.
252301
#[inline(always)]
253302
pub fn set(&mut self, bits: REG::Ux) -> &mut Self {
@@ -335,7 +384,8 @@ pub struct RangeFrom<const MIN: u64>;
335384
pub struct RangeTo<const MAX: u64>;
336385

337386
/// Write field Proxy
338-
pub type FieldWriter<'a, REG, const WI: u8, FI = u8, Safety = Unsafe> = raw::FieldWriter<'a, REG, WI, FI, Safety>;
387+
pub type FieldWriter<'a, REG, const WI: u8, FI = u8, Safety = Unsafe> =
388+
raw::FieldWriter<'a, REG, WI, FI, Safety>;
339389

340390
impl<REG, const WI: u8, FI, Safety> FieldWriter<'_, REG, WI, FI, Safety>
341391
where
@@ -390,7 +440,8 @@ where
390440
}
391441
}
392442

393-
impl<'a, REG, const WI: u8, FI, const MIN: u64, const MAX: u64> FieldWriter<'a, REG, WI, FI, Range<MIN, MAX>>
443+
impl<'a, REG, const WI: u8, FI, const MIN: u64, const MAX: u64>
444+
FieldWriter<'a, REG, WI, FI, Range<MIN, MAX>>
394445
where
395446
REG: Writable + RegisterSpec,
396447
FI: FieldSpec,
@@ -478,7 +529,7 @@ macro_rules! bit_proxy {
478529
pub const fn width(&self) -> u8 {
479530
Self::WIDTH
480531
}
481-
532+
482533
/// Field offset
483534
#[inline(always)]
484535
pub const fn offset(&self) -> u8 {

src/generate/peripheral.rs

+1-47
Original file line numberDiff line numberDiff line change
@@ -62,25 +62,6 @@ pub fn render(p_original: &Peripheral, index: &Index, config: &Config) -> Result
6262
feature_attribute.extend(quote! { #[cfg(feature = #feature_name)] });
6363
};
6464

65-
let steal_fn = quote! {
66-
/// Steal an instance of this peripheral
67-
///
68-
/// # Safety
69-
///
70-
/// Ensure that the new instance of the peripheral cannot be used in a way
71-
/// that may race with any existing instances, for example by only
72-
/// accessing read-only or write-only registers, or by consuming the
73-
/// original peripheral and using critical sections to coordinate
74-
/// access between multiple new instances.
75-
///
76-
/// Additionally, other software such as HALs may rely on only one
77-
/// peripheral instance existing to ensure memory safety; ensure
78-
/// no stolen instances are passed to such software.
79-
pub unsafe fn steal() -> Self {
80-
Self { _marker: PhantomData }
81-
}
82-
};
83-
8465
let phtml = config.settings.html_url.as_ref().map(|url| {
8566
let doc = format!("See peripheral [structure]({url}#{})", &path.peripheral);
8667
quote!(#[doc = ""] #[doc = #doc])
@@ -97,34 +78,7 @@ pub fn render(p_original: &Peripheral, index: &Index, config: &Config) -> Result
9778
#phtml
9879
#doc_alias
9980
#feature_attribute
100-
pub struct #p_ty { _marker: PhantomData<*const ()> }
101-
102-
#feature_attribute
103-
unsafe impl Send for #p_ty {}
104-
105-
#feature_attribute
106-
impl #p_ty {
107-
///Pointer to the register block
108-
pub const PTR: *const #base::RegisterBlock = #address as *const _;
109-
110-
///Return the pointer to the register block
111-
#[inline(always)]
112-
pub const fn ptr() -> *const #base::RegisterBlock {
113-
Self::PTR
114-
}
115-
116-
#steal_fn
117-
}
118-
119-
#feature_attribute
120-
impl Deref for #p_ty {
121-
type Target = #base::RegisterBlock;
122-
123-
#[inline(always)]
124-
fn deref(&self) -> &Self::Target {
125-
unsafe { &*Self::PTR }
126-
}
127-
}
81+
pub type #p_ty = crate::Periph<#base::RegisterBlock, #address>;
12882

12983
#feature_attribute
13084
impl core::fmt::Debug for #p_ty {

0 commit comments

Comments
 (0)