Skip to content

Commit 8023ea0

Browse files
authored
Merge pull request #910 from rust-embedded/generic-periph
use generics for peripherals too
2 parents d352aeb + 6b0e1ca commit 8023ea0

File tree

4 files changed

+57
-56
lines changed

4 files changed

+57
-56
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
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

Lines changed: 0 additions & 5 deletions
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

Lines changed: 55 additions & 4 deletions
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

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

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

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

0 commit comments

Comments
 (0)