#![doc(html_root_url = "https://docs.rs/ruspiro-register/0.5.5")]
#![no_std]
use core::cmp::PartialEq;
use core::fmt;
use core::ops::{BitAnd, BitOr, Not, Shl, Shr};
mod macros;
pub trait RegisterType:
Copy
+ Clone
+ PartialEq
+ BitOr<Output = Self>
+ BitAnd<Output = Self>
+ Not<Output = Self>
+ Shl<Self, Output = Self>
+ Shr<Self, Output = Self>
{
}
#[doc(hidden)]
macro_rules! registertype_impl {
($( $t:ty ),*) => ($(
impl RegisterType for $t { }
)*)
}
registertype_impl![u8, u16, u32, u64];
#[derive(Copy, Clone)]
pub struct RegisterField<T: RegisterType> {
mask: T,
shift: T,
}
#[derive(Copy, Clone)]
pub struct RegisterFieldValue<T: RegisterType> {
field: RegisterField<T>,
value: T,
}
#[doc(hidden)]
macro_rules! registerfield_impl {
($($t:ty),*) => ($(
impl RegisterField<$t> {
#[inline]
#[allow(dead_code)]
pub const fn new(mask: $t, shift: $t) -> RegisterField<$t> {
Self {
mask,
shift,
}
}
#[inline]
#[allow(dead_code)]
pub fn mask(&self) -> $t {
self.mask.checked_shl(self.shift as u32).unwrap_or(0)
}
#[allow(dead_code)]
#[inline]
pub fn shift(&self) -> $t {
self.shift
}
}
impl fmt::Debug for RegisterField<$t> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut high_bit = self.shift;
let mut mask = self.mask;
while mask > 0 {
high_bit += 1;
mask >>= 1;
};
high_bit -= 1;
write!(f, "RegisterField {{\n Bits: [{}:{}]\n Mask: {:#b}\n}}",
high_bit, self.shift, self.mask.checked_shl(self.shift as u32).unwrap_or(0))
}
}
impl RegisterFieldValue<$t> {
#[inline]
#[allow(dead_code)]
pub const fn new(field: RegisterField<$t>, value: $t) -> Self {
RegisterFieldValue {
field,
value: value & field.mask
}
}
#[inline]
#[allow(dead_code)]
pub const fn from_raw(field: RegisterField<$t>, raw_value: $t) -> Self {
RegisterFieldValue {
field,
value: (raw_value >> field.shift) & field.mask
}
}
#[inline]
#[allow(dead_code)]
pub fn value(&self) -> $t {
self.value }
#[inline]
#[allow(dead_code)]
pub fn raw_value(&self) -> $t {
self.value.checked_shl(self.field.shift as u32).unwrap_or(0)
}
#[inline]
#[allow(dead_code)]
pub fn mask(&self) -> $t {
self.field.mask()
}
}
impl fmt::Debug for RegisterFieldValue<$t> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("RegisterFieldValue")
.field("field", &self.field)
.field("value", &self.value)
.field("raw_value", &self.raw_value())
.finish()
}
}
impl PartialEq for RegisterFieldValue<$t> {
fn eq(&self, other: &Self) -> bool {
self.value() == other.value()
}
}
impl BitOr for RegisterFieldValue<$t> {
type Output = RegisterFieldValue<$t>;
#[inline]
#[allow(dead_code)]
fn bitor(self, rhs: RegisterFieldValue<$t>) -> Self {
let field = RegisterField::<$t>::new( self.field.mask() | rhs.field.mask(), 0);
RegisterFieldValue {
field,
value: (self.raw_value() | rhs.raw_value()),
}
}
}
impl BitAnd for RegisterFieldValue<$t> {
type Output = RegisterFieldValue<$t>;
#[inline]
#[allow(dead_code)]
fn bitand(self, rhs: RegisterFieldValue<$t>) -> Self {
let field = RegisterField::<$t>::new( self.field.mask() & rhs.field.mask(), 0);
RegisterFieldValue {
field,
value: (self.raw_value() & rhs.raw_value()),
}
}
}
)*);
}
registerfield_impl![u8, u16, u32, u64];