Skip to content

FieldSpec #722

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

Merged
merged 1 commit into from
Jun 4, 2023
Merged
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]

- `FieldFpec` instead or `fty` generic
- print error on ci `curl` request fail
- removed `rty` generic in `FieldWriter`
- `bool` and `u8` as default generics for `BitReader/Writer` and `FieldReader/Writer`
Expand Down
91 changes: 48 additions & 43 deletions src/generate/generic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ macro_rules! raw_reg {
const fn $mask<const WI: u8>() -> $U {
<$U>::MAX >> ($size - WI)
}
impl FieldSpec for $U {
type Ux = $U;
}
};
}

Expand All @@ -47,6 +50,12 @@ pub trait RegisterSpec {
type Ux: RawReg;
}

/// Raw field type
pub trait FieldSpec: Sized {
/// Raw field type (`u8`, `u16`, `u32`, ...).
type Ux: Copy + PartialEq + From<Self>;
}

/// Trait implemented by readable registers to enable the `read` method.
///
/// Registers marked with `Writable` can be also be `modify`'ed.
Expand Down Expand Up @@ -301,19 +310,19 @@ impl<REG: RegisterSpec> W<REG> {
}

#[doc(hidden)]
pub struct FieldReaderRaw<U, FI> {
pub(crate) bits: U,
pub struct FieldReaderRaw<FI = u8>
where
FI: FieldSpec
{
pub(crate) bits: FI::Ux,
_reg: marker::PhantomData<FI>,
}

impl<U, FI> FieldReaderRaw<U, FI>
where
U: Copy,
{
impl<FI: FieldSpec> FieldReaderRaw<FI> {
/// Creates a new instance of the reader.
#[allow(unused)]
#[inline(always)]
pub(crate) fn new(bits: U) -> Self {
pub(crate) fn new(bits: FI::Ux) -> Self {
Self {
bits,
_reg: marker::PhantomData,
Expand All @@ -322,7 +331,7 @@ where
}

#[doc(hidden)]
pub struct BitReaderRaw<FI> {
pub struct BitReaderRaw<FI = bool> {
pub(crate) bits: bool,
_reg: marker::PhantomData<FI>,
}
Expand All @@ -342,30 +351,26 @@ impl<FI> BitReaderRaw<FI> {
/// Field reader.
///
/// Result of the `read` methods of fields.
pub type FieldReader<N = u8, FI = u8> = FieldReaderRaw<N, FI>;
pub type FieldReader<FI = u8> = FieldReaderRaw<FI>;

/// Bit-wise field reader
pub type BitReader<FI = bool> = BitReaderRaw<FI>;

impl<N, FI> FieldReader<N, FI>
where
N: Copy,
{
impl<FI: FieldSpec> FieldReader<FI> {
/// Reads raw bits from field.
#[inline(always)]
pub fn bits(&self) -> N {
pub fn bits(&self) -> FI::Ux {
self.bits
}
}

impl<N, FI> PartialEq<FI> for FieldReader<N, FI>
impl<FI> PartialEq<FI> for FieldReader<FI>
where
FI: Copy,
N: PartialEq + From<FI>,
FI: FieldSpec + Copy,
{
#[inline(always)]
fn eq(&self, other: &FI) -> bool {
self.bits.eq(&N::from(*other))
self.bits.eq(&FI::Ux::from(*other))
}
}

Expand Down Expand Up @@ -404,20 +409,20 @@ pub struct Safe;
pub struct Unsafe;

#[doc(hidden)]
pub struct FieldWriterRaw<'a, REG, const WI: u8, const O: u8, N, FI, Safety>
pub struct FieldWriterRaw<'a, REG, const WI: u8, const O: u8, FI = u8, Safety = Unsafe>
where
REG: Writable + RegisterSpec,
N: From<FI>,
FI: FieldSpec,
{
pub(crate) w: &'a mut REG::Writer,
_field: marker::PhantomData<(N, FI, Safety)>,
_field: marker::PhantomData<(FI, Safety)>,
}

impl<'a, REG, const WI: u8, const O: u8, N, FI, Safety>
FieldWriterRaw<'a, REG, WI, O, N, FI, Safety>
impl<'a, REG, const WI: u8, const O: u8, FI, Safety>
FieldWriterRaw<'a, REG, WI, O, FI, Safety>
where
REG: Writable + RegisterSpec,
N: From<FI>,
FI: FieldSpec,
{
/// Creates a new instance of the writer
#[allow(unused)]
Expand All @@ -431,7 +436,7 @@ where
}

#[doc(hidden)]
pub struct BitWriterRaw<'a, REG, const O: u8, FI, M>
pub struct BitWriterRaw<'a, REG, const O: u8, FI = bool, M = BitM>
where
REG: Writable + RegisterSpec,
bool: From<FI>,
Expand All @@ -457,25 +462,25 @@ where
}

/// Write field Proxy with unsafe `bits`
pub type FieldWriter<'a, REG, const WI: u8, const O: u8, N = u8, FI = u8> =
FieldWriterRaw<'a, REG, WI, O, N, FI, Unsafe>;
pub type FieldWriter<'a, REG, const WI: u8, const O: u8, FI = u8> =
FieldWriterRaw<'a, REG, WI, O, FI, Unsafe>;
/// Write field Proxy with safe `bits`
pub type FieldWriterSafe<'a, REG, const WI: u8, const O: u8, N = u8, FI = u8> =
FieldWriterRaw<'a, REG, WI, O, N, FI, Safe>;
pub type FieldWriterSafe<'a, REG, const WI: u8, const O: u8, FI = u8> =
FieldWriterRaw<'a, REG, WI, O, FI, Safe>;

impl<'a, REG, const WI: u8, const OF: u8, N, FI> FieldWriter<'a, REG, WI, OF, N, FI>
impl<'a, REG, const WI: u8, const OF: u8, FI> FieldWriter<'a, REG, WI, OF, FI>
where
REG: Writable + RegisterSpec,
N: From<FI>,
FI: FieldSpec,
{
/// Field width
pub const WIDTH: u8 = WI;
}

impl<'a, REG, const WI: u8, const OF: u8, N, FI> FieldWriterSafe<'a, REG, WI, OF, N, FI>
impl<'a, REG, const WI: u8, const OF: u8, FI> FieldWriterSafe<'a, REG, WI, OF, FI>
where
REG: Writable + RegisterSpec,
N: From<FI>,
FI: FieldSpec,
{
/// Field width
pub const WIDTH: u8 = WI;
Expand Down Expand Up @@ -531,46 +536,46 @@ bit_proxy!(BitWriter0S, Bit0S);
bit_proxy!(BitWriter1T, Bit1T);
bit_proxy!(BitWriter0T, Bit0T);

impl<'a, REG, const WI: u8, const OF: u8, N, FI> FieldWriter<'a, REG, WI, OF, N, FI>
impl<'a, REG, const WI: u8, const OF: u8, FI> FieldWriter<'a, REG, WI, OF, FI>
where
REG: Writable + RegisterSpec,
REG::Ux: From<N>,
N: From<FI>,
FI: FieldSpec,
REG::Ux: From<FI::Ux>,
{
/// Writes raw bits to the field
///
/// # Safety
///
/// Passing incorrect value can cause undefined behaviour. See reference manual
#[inline(always)]
pub unsafe fn bits(self, value: N) -> &'a mut REG::Writer {
pub unsafe fn bits(self, value: FI::Ux) -> &'a mut REG::Writer {
self.w.bits &= !(REG::Ux::mask::<WI>() << OF);
self.w.bits |= (REG::Ux::from(value) & REG::Ux::mask::<WI>()) << OF;
self.w
}
/// Writes `variant` to the field
#[inline(always)]
pub fn variant(self, variant: FI) -> &'a mut REG::Writer {
unsafe { self.bits(N::from(variant)) }
unsafe { self.bits(FI::Ux::from(variant)) }
}
}
impl<'a, REG, const WI: u8, const OF: u8, N, FI> FieldWriterSafe<'a, REG, WI, OF, N, FI>
impl<'a, REG, const WI: u8, const OF: u8, FI> FieldWriterSafe<'a, REG, WI, OF, FI>
where
REG: Writable + RegisterSpec,
REG::Ux: From<N>,
N: From<FI>,
FI: FieldSpec,
REG::Ux: From<FI::Ux>,
{
/// Writes raw bits to the field
#[inline(always)]
pub fn bits(self, value: N) -> &'a mut REG::Writer {
pub fn bits(self, value: FI::Ux) -> &'a mut REG::Writer {
self.w.bits &= !(REG::Ux::mask::<WI>() << OF);
self.w.bits |= (REG::Ux::from(value) & REG::Ux::mask::<WI>()) << OF;
self.w
}
/// Writes `variant` to the field
#[inline(always)]
pub fn variant(self, variant: FI) -> &'a mut REG::Writer {
self.bits(N::from(variant))
self.bits(FI::Ux::from(variant))
}
}

Expand Down
26 changes: 18 additions & 8 deletions src/generate/register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -691,12 +691,10 @@ pub fn fields(
} else {
quote! { crate::BitReader<#value_read_ty> }
}
} else if fty == "u8" && value_read_ty == "u8" {
quote! { crate::FieldReader }
} else if value_read_ty == "u8" {
quote! { crate::FieldReader<#fty> }
quote! { crate::FieldReader }
} else {
quote! { crate::FieldReader<#fty, #value_read_ty> }
quote! { crate::FieldReader<#value_read_ty> }
};
let mut readerdoc = field_reader_brief.clone();
if let Some(action) = f.read_action {
Expand Down Expand Up @@ -1032,12 +1030,10 @@ pub fn fields(
span,
);
let width = &util::unsuffixed(width as _);
if fty == "u8" && value_write_ty == "u8" {
if value_write_ty == "u8" {
quote! { crate::#wproxy<'a, #regspec_ident, #width, O> }
} else if value_write_ty == "u8" {
quote! { crate::#wproxy<'a, #regspec_ident, #width, O, #fty> }
} else {
quote! { crate::#wproxy<'a, #regspec_ident, #width, O, #fty, #value_write_ty> }
quote! { crate::#wproxy<'a, #regspec_ident, #width, O, #value_write_ty> }
}
};
mod_items.extend(quote! {
Expand Down Expand Up @@ -1246,6 +1242,13 @@ fn add_with_no_variants(
}
}
});
if fty != "bool" {
mod_items.extend(quote! {
impl crate::FieldSpec for #pc {
type Ux = #fty;
}
});
}
}

fn add_from_variants(
Expand Down Expand Up @@ -1295,6 +1298,13 @@ fn add_from_variants(
}
}
});
if fty != "bool" {
mod_items.extend(quote! {
impl crate::FieldSpec for #pc {
type Ux = #fty;
}
});
}
}

fn calculate_offset(
Expand Down