[del] tock-registers: Replace manual repeated impls with macros
This commit is contained in:
parent
0cf8a88f12
commit
b3ddfc5665
|
@ -11,5 +11,6 @@ rustflags = [
|
||||||
"-C", "target-feature=-fp-armv8",
|
"-C", "target-feature=-fp-armv8",
|
||||||
"-C", "target-cpu=cortex-a53",
|
"-C", "target-cpu=cortex-a53",
|
||||||
"-C", "embed-bitcode=yes",
|
"-C", "embed-bitcode=yes",
|
||||||
|
"-Z", "macro-backtrace",
|
||||||
]
|
]
|
||||||
runner = "cargo make test-runner"
|
runner = "cargo make test-runner"
|
||||||
|
|
|
@ -79,32 +79,20 @@ pub trait IntLike:
|
||||||
fn zero() -> Self;
|
fn zero() -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IntLike for u8 {
|
macro_rules! IntLike_impl_for {
|
||||||
|
( $( $type:ty ),+ $(,)? ) => {
|
||||||
|
$(
|
||||||
|
impl IntLike for $type {
|
||||||
fn zero() -> Self {
|
fn zero() -> Self {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl IntLike for u16 {
|
)*
|
||||||
fn zero() -> Self {
|
};
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl IntLike for u32 {
|
|
||||||
fn zero() -> Self {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl IntLike for u64 {
|
|
||||||
fn zero() -> Self {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl IntLike for u128 {
|
|
||||||
fn zero() -> Self {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IntLike_impl_for!(u8, u16, u32, u64, u128);
|
||||||
|
|
||||||
/// Descriptive name for each register.
|
/// Descriptive name for each register.
|
||||||
pub trait RegisterLongName {}
|
pub trait RegisterLongName {}
|
||||||
|
|
||||||
|
@ -408,29 +396,19 @@ impl<T: IntLike + fmt::Debug, R: RegisterLongName> fmt::Debug for LocalRegisterC
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: RegisterLongName> From<LocalRegisterCopy<u8, R>> for u8 {
|
macro_rules! From_impl_for {
|
||||||
fn from(r: LocalRegisterCopy<u8, R>) -> u8 {
|
( $( $type:ty ),+ $(,)? ) => {
|
||||||
|
$(
|
||||||
|
impl<R: RegisterLongName> From<LocalRegisterCopy<$type, R>> for $type {
|
||||||
|
fn from(r: LocalRegisterCopy<$type, R>) -> $type {
|
||||||
r.value
|
r.value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
)*
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
impl<R: RegisterLongName> From<LocalRegisterCopy<u16, R>> for u16 {
|
From_impl_for!(u8, u16, u32, u64, u128);
|
||||||
fn from(r: LocalRegisterCopy<u16, R>) -> u16 {
|
|
||||||
r.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<R: RegisterLongName> From<LocalRegisterCopy<u32, R>> for u32 {
|
|
||||||
fn from(r: LocalRegisterCopy<u32, R>) -> u32 {
|
|
||||||
r.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<R: RegisterLongName> From<LocalRegisterCopy<u64, R>> for u64 {
|
|
||||||
fn from(r: LocalRegisterCopy<u64, R>) -> u64 {
|
|
||||||
r.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// In memory volatile register.
|
/// In memory volatile register.
|
||||||
// To successfully alias this structure onto hardware registers in memory, this
|
// To successfully alias this structure onto hardware registers in memory, this
|
||||||
|
@ -506,6 +484,8 @@ impl<T: IntLike, R: RegisterLongName> InMemoryRegister<T, R> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Specific section of a register.
|
/// Specific section of a register.
|
||||||
|
///
|
||||||
|
/// For the Field, the mask is unshifted, ie. the LSB should always be set.
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct Field<T: IntLike, R: RegisterLongName> {
|
pub struct Field<T: IntLike, R: RegisterLongName> {
|
||||||
mask: T,
|
mask: T,
|
||||||
|
@ -514,6 +494,14 @@ pub struct Field<T: IntLike, R: RegisterLongName> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: IntLike, R: RegisterLongName> Field<T, R> {
|
impl<T: IntLike, R: RegisterLongName> Field<T, R> {
|
||||||
|
pub const fn new(mask: T, shift: usize) -> Field<T, R> {
|
||||||
|
Field {
|
||||||
|
mask: mask,
|
||||||
|
shift: shift,
|
||||||
|
associated_register: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the raw bitmask used by this Field.
|
/// Get the raw bitmask used by this Field.
|
||||||
pub fn mask(&self) -> T {
|
pub fn mask(&self) -> T {
|
||||||
(self.mask as T) << self.shift
|
(self.mask as T) << self.shift
|
||||||
|
@ -537,66 +525,24 @@ impl<T: IntLike, R: RegisterLongName> Field<T, R> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// For the Field, the mask is unshifted, ie. the LSB should always be set
|
macro_rules! Field_impl_for {
|
||||||
impl<R: RegisterLongName> Field<u8, R> {
|
( $( $type:ty ),+ $(,)? ) => {
|
||||||
pub const fn new(mask: u8, shift: usize) -> Field<u8, R> {
|
$(
|
||||||
Field {
|
impl<R: RegisterLongName> Field<$type, R> {
|
||||||
mask: mask,
|
pub fn val(&self, value: $type) -> FieldValue<$type, R> {
|
||||||
shift: shift,
|
FieldValue::<$type, R>::new(self.mask, self.shift, value)
|
||||||
associated_register: PhantomData,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
)*
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
pub fn val(&self, value: u8) -> FieldValue<u8, R> {
|
Field_impl_for!(u8, u16, u32, u64, u128);
|
||||||
FieldValue::<u8, R>::new(self.mask, self.shift, value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<R: RegisterLongName> Field<u16, R> {
|
|
||||||
pub const fn new(mask: u16, shift: usize) -> Field<u16, R> {
|
|
||||||
Field {
|
|
||||||
mask: mask,
|
|
||||||
shift: shift,
|
|
||||||
associated_register: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn val(&self, value: u16) -> FieldValue<u16, R> {
|
|
||||||
FieldValue::<u16, R>::new(self.mask, self.shift, value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<R: RegisterLongName> Field<u32, R> {
|
|
||||||
pub const fn new(mask: u32, shift: usize) -> Field<u32, R> {
|
|
||||||
Field {
|
|
||||||
mask: mask,
|
|
||||||
shift: shift,
|
|
||||||
associated_register: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn val(&self, value: u32) -> FieldValue<u32, R> {
|
|
||||||
FieldValue::<u32, R>::new(self.mask, self.shift, value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<R: RegisterLongName> Field<u64, R> {
|
|
||||||
pub const fn new(mask: u64, shift: usize) -> Field<u64, R> {
|
|
||||||
Field {
|
|
||||||
mask: mask,
|
|
||||||
shift: shift,
|
|
||||||
associated_register: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn val(&self, value: u64) -> FieldValue<u64, R> {
|
|
||||||
FieldValue::<u64, R>::new(self.mask, self.shift, value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Values for the specific register fields.
|
/// Values for the specific register fields.
|
||||||
// For the FieldValue, the masks and values are shifted into their actual
|
///
|
||||||
// location in the register.
|
/// For the FieldValue, the masks and values are shifted into their actual
|
||||||
|
/// location in the register.
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct FieldValue<T: IntLike, R: RegisterLongName> {
|
pub struct FieldValue<T: IntLike, R: RegisterLongName> {
|
||||||
mask: T,
|
mask: T,
|
||||||
|
@ -604,11 +550,14 @@ pub struct FieldValue<T: IntLike, R: RegisterLongName> {
|
||||||
associated_register: PhantomData<R>,
|
associated_register: PhantomData<R>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! FieldValue_impl_for {
|
||||||
|
( $( $type:ty ),+ $(,)? ) => {
|
||||||
|
$(
|
||||||
// Necessary to split the implementation of new() out because the bitwise
|
// Necessary to split the implementation of new() out because the bitwise
|
||||||
// math isn't treated as const when the type is generic.
|
// math isn't treated as const when the type is generic.
|
||||||
// Tracking issue: https://github.com/rust-lang/rfcs/pull/2632
|
// Tracking issue: https://github.com/rust-lang/rfcs/pull/2632
|
||||||
impl<R: RegisterLongName> FieldValue<u8, R> {
|
impl<R: RegisterLongName> FieldValue<$type, R> {
|
||||||
pub const fn new(mask: u8, shift: usize, value: u8) -> Self {
|
pub const fn new(mask: $type, shift: usize, value: $type) -> Self {
|
||||||
FieldValue {
|
FieldValue {
|
||||||
mask: mask << shift,
|
mask: mask << shift,
|
||||||
value: (value & mask) << shift,
|
value: (value & mask) << shift,
|
||||||
|
@ -616,64 +565,22 @@ impl<R: RegisterLongName> FieldValue<u8, R> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Necessary to split the implementation of From<> out because of the orphan rule
|
||||||
impl<R: RegisterLongName> From<FieldValue<u8, R>> for u8 {
|
// for foreign trait implementation (see [E0210](https://doc.rust-lang.org/error-index.html#E0210)).
|
||||||
fn from(val: FieldValue<u8, R>) -> u8 {
|
impl<R: RegisterLongName> From<FieldValue<$type, R>> for $type {
|
||||||
|
fn from(val: FieldValue<$type, R>) -> $type {
|
||||||
val.value
|
val.value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
)*
|
||||||
impl<R: RegisterLongName> FieldValue<u16, R> {
|
};
|
||||||
pub const fn new(mask: u16, shift: usize, value: u16) -> Self {
|
|
||||||
FieldValue {
|
|
||||||
mask: mask << shift,
|
|
||||||
value: (value & mask) << shift,
|
|
||||||
associated_register: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: RegisterLongName> From<FieldValue<u16, R>> for u16 {
|
FieldValue_impl_for!(u8, u16, u32, u64, u128);
|
||||||
fn from(val: FieldValue<u16, R>) -> u16 {
|
|
||||||
val.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<R: RegisterLongName> FieldValue<u32, R> {
|
|
||||||
pub const fn new(mask: u32, shift: usize, value: u32) -> Self {
|
|
||||||
FieldValue {
|
|
||||||
mask: mask << shift,
|
|
||||||
value: (value & mask) << shift,
|
|
||||||
associated_register: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<R: RegisterLongName> From<FieldValue<u32, R>> for u32 {
|
|
||||||
fn from(val: FieldValue<u32, R>) -> u32 {
|
|
||||||
val.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<R: RegisterLongName> FieldValue<u64, R> {
|
|
||||||
pub const fn new(mask: u64, shift: usize, value: u64) -> Self {
|
|
||||||
FieldValue {
|
|
||||||
mask: mask << shift,
|
|
||||||
value: (value & mask) << shift,
|
|
||||||
associated_register: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<R: RegisterLongName> From<FieldValue<u64, R>> for u64 {
|
|
||||||
fn from(val: FieldValue<u64, R>) -> u64 {
|
|
||||||
val.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: IntLike, R: RegisterLongName> FieldValue<T, R> {
|
impl<T: IntLike, R: RegisterLongName> FieldValue<T, R> {
|
||||||
/// Get the raw bitmask represented by this FieldValue.
|
/// Get the raw bitmask represented by this FieldValue.
|
||||||
pub fn mask(self) -> T {
|
pub fn mask(&self) -> T {
|
||||||
self.mask as T
|
self.mask as T
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue