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

use generics for peripherals too #910

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/).

## [Unreleased]

- Generic `Periph<RB, A>`
- Add `mtvec_align` field to `riscv_config` to configure the byte alignment of interrupt vector table.
- Fix reexport path when "%s" inside "derivedFrom"
- Force using rust edition 2021 in CI
Expand Down
5 changes: 0 additions & 5 deletions src/generate/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,6 @@ pub fn render(d: &Device, config: &Config, device_x: &mut String) -> Result<Toke
});
}

out.extend(quote! {
use core::ops::Deref;
use core::marker::PhantomData;
});

// Retaining the previous assumption
let mut fpu_present = true;

Expand Down
59 changes: 55 additions & 4 deletions src/generate/generic.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,51 @@
use core::marker;

/// Generic peripheral accessor
pub struct Periph<RB, const A: usize> {
_marker: marker::PhantomData<RB>,
}

unsafe impl<RB, const A: usize> Send for Periph<RB, A> {}

impl<RB, const A: usize> Periph<RB, A> {
///Pointer to the register block
pub const PTR: *const RB = A as *const _;

///Return the pointer to the register block
#[inline(always)]
pub const fn ptr() -> *const RB {
Self::PTR
}

/// Steal an instance of this peripheral
///
/// # Safety
///
/// Ensure that the new instance of the peripheral cannot be used in a way
/// that may race with any existing instances, for example by only
/// accessing read-only or write-only registers, or by consuming the
/// original peripheral and using critical sections to coordinate
/// access between multiple new instances.
///
/// Additionally, other software such as HALs may rely on only one
/// peripheral instance existing to ensure memory safety; ensure
/// no stolen instances are passed to such software.
pub unsafe fn steal() -> Self {
Self {
_marker: marker::PhantomData,
}
}
}

impl<RB, const A: usize> core::ops::Deref for Periph<RB, A> {
type Target = RB;

#[inline(always)]
fn deref(&self) -> &Self::Target {
unsafe { &*Self::PTR }
}
}

/// Raw register type (`u8`, `u16`, `u32`, ...)
pub trait RawReg:
Copy
Expand Down Expand Up @@ -247,7 +293,10 @@ impl<REG: Writable> W<REG> {
self
}
}
impl<REG> W<REG> where REG: Writable<Safety = Safe> {
impl<REG> W<REG>
where
REG: Writable<Safety = Safe>,
{
/// Writes raw bits to the register.
#[inline(always)]
pub fn set(&mut self, bits: REG::Ux) -> &mut Self {
Expand Down Expand Up @@ -335,7 +384,8 @@ pub struct RangeFrom<const MIN: u64>;
pub struct RangeTo<const MAX: u64>;

/// Write field Proxy
pub type FieldWriter<'a, REG, const WI: u8, FI = u8, Safety = Unsafe> = raw::FieldWriter<'a, REG, WI, FI, Safety>;
pub type FieldWriter<'a, REG, const WI: u8, FI = u8, Safety = Unsafe> =
raw::FieldWriter<'a, REG, WI, FI, Safety>;

impl<REG, const WI: u8, FI, Safety> FieldWriter<'_, REG, WI, FI, Safety>
where
Expand Down Expand Up @@ -390,7 +440,8 @@ where
}
}

impl<'a, REG, const WI: u8, FI, const MIN: u64, const MAX: u64> FieldWriter<'a, REG, WI, FI, Range<MIN, MAX>>
impl<'a, REG, const WI: u8, FI, const MIN: u64, const MAX: u64>
FieldWriter<'a, REG, WI, FI, Range<MIN, MAX>>
where
REG: Writable + RegisterSpec,
FI: FieldSpec,
Expand Down Expand Up @@ -478,7 +529,7 @@ macro_rules! bit_proxy {
pub const fn width(&self) -> u8 {
Self::WIDTH
}

/// Field offset
#[inline(always)]
pub const fn offset(&self) -> u8 {
Expand Down
48 changes: 1 addition & 47 deletions src/generate/peripheral.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,25 +62,6 @@ pub fn render(p_original: &Peripheral, index: &Index, config: &Config) -> Result
feature_attribute.extend(quote! { #[cfg(feature = #feature_name)] });
};

let steal_fn = quote! {
/// Steal an instance of this peripheral
///
/// # Safety
///
/// Ensure that the new instance of the peripheral cannot be used in a way
/// that may race with any existing instances, for example by only
/// accessing read-only or write-only registers, or by consuming the
/// original peripheral and using critical sections to coordinate
/// access between multiple new instances.
///
/// Additionally, other software such as HALs may rely on only one
/// peripheral instance existing to ensure memory safety; ensure
/// no stolen instances are passed to such software.
pub unsafe fn steal() -> Self {
Self { _marker: PhantomData }
}
};

let phtml = config.settings.html_url.as_ref().map(|url| {
let doc = format!("See peripheral [structure]({url}#{})", &path.peripheral);
quote!(#[doc = ""] #[doc = #doc])
Expand All @@ -97,34 +78,7 @@ pub fn render(p_original: &Peripheral, index: &Index, config: &Config) -> Result
#phtml
#doc_alias
#feature_attribute
pub struct #p_ty { _marker: PhantomData<*const ()> }

#feature_attribute
unsafe impl Send for #p_ty {}

#feature_attribute
impl #p_ty {
///Pointer to the register block
pub const PTR: *const #base::RegisterBlock = #address as *const _;

///Return the pointer to the register block
#[inline(always)]
pub const fn ptr() -> *const #base::RegisterBlock {
Self::PTR
}

#steal_fn
}

#feature_attribute
impl Deref for #p_ty {
type Target = #base::RegisterBlock;

#[inline(always)]
fn deref(&self) -> &Self::Target {
unsafe { &*Self::PTR }
}
}
pub type #p_ty = crate::Periph<#base::RegisterBlock, #address>;

#feature_attribute
impl core::fmt::Debug for #p_ty {
Expand Down