From cb6e0d3b692a7b4d2353601c5d41b136268e2f2d Mon Sep 17 00:00:00 2001 From: Dylan McKay Date: Thu, 14 Dec 2017 02:13:24 +1300 Subject: [PATCH] Invert the direction of the Register type parameter --- build.rs | 39 +++++++++--------- src/modules/spi/mod.rs | 6 +-- src/modules/timer/timer16.rs | 50 +++++++++++----------- src/modules/timer/timer8.rs | 42 +++++++++---------- src/modules/usart.rs | 10 ++--- src/pin.rs | 6 +-- src/register.rs | 80 +++++++++++++++++------------------- 7 files changed, 115 insertions(+), 118 deletions(-) diff --git a/build.rs b/build.rs index 6a16bcc..73d9814 100644 --- a/build.rs +++ b/build.rs @@ -102,7 +102,7 @@ mod gen { writeln!(w, "impl {} {{", register.name)?; for bitfield in register.bitfields.iter() { // Create a mask for the whole bitset. - writeln!(w, " pub const {}: Bitset<{}, Self> = Bitset::new(0x{:x});", bitfield.name, ty, bitfield.mask)?; + writeln!(w, " pub const {}: Bitset = Bitset::new(0x{:x});", bitfield.name, bitfield.mask)?; // We create masks for the individual bits in the field if there // is more than one bit in the field. @@ -110,8 +110,8 @@ mod gen { let mut current_mask_bit_num = 0; for current_register_bit_num in 0..15 { if (current_mask & 0b1) == 0b1 { - writeln!(w, " pub const {}{}: Mask<{}, Self> = Mask::new(1<<{});", - bitfield.name, current_mask_bit_num, ty, current_register_bit_num)?; + writeln!(w, " pub const {}{}: Mask = Mask::new(1<<{});", + bitfield.name, current_mask_bit_num, current_register_bit_num)?; current_mask_bit_num += 1; } @@ -122,7 +122,8 @@ mod gen { writeln!(w, "}}")?; writeln!(w)?; - writeln!(w, "impl Register<{}> for {} {{", ty, register.name)?; + writeln!(w, "impl Register for {} {{", register.name)?; + writeln!(w, " type T = {};", ty)?; writeln!(w, " const ADDR: *mut {} = 0x{:x} as *mut {};", ty, register.offset, ty)?; writeln!(w, "}}")?; } @@ -266,13 +267,13 @@ mod gen { writeln!(w, " type ControlB = {};", find_reg_suffix("TCCR", "B").name)?; writeln!(w, " type InterruptMask = {};", find_reg("TIMSK").name)?; writeln!(w, " type InterruptFlag = {};", find_reg("TIFR").name)?; - writeln!(w, " const CS0: Mask = Self::ControlB::CS00;")?; - writeln!(w, " const CS1: Mask = Self::ControlB::CS01;")?; - writeln!(w, " const CS2: Mask = Self::ControlB::CS02;")?; - writeln!(w, " const WGM0: Mask = Self::ControlA::WGM00;")?; - writeln!(w, " const WGM1: Mask = Self::ControlA::WGM01;")?; - writeln!(w, " const WGM2: Mask = Self::ControlB::WGM020;")?; - writeln!(w, " const OCIEA: Bitset = Self::InterruptMask::OCIE0A;")?; + writeln!(w, " const CS0: Mask = Self::ControlB::CS00;")?; + writeln!(w, " const CS1: Mask = Self::ControlB::CS01;")?; + writeln!(w, " const CS2: Mask = Self::ControlB::CS02;")?; + writeln!(w, " const WGM0: Mask = Self::ControlA::WGM00;")?; + writeln!(w, " const WGM1: Mask = Self::ControlA::WGM01;")?; + writeln!(w, " const WGM2: Mask = Self::ControlB::WGM020;")?; + writeln!(w, " const OCIEA: Bitset = Self::InterruptMask::OCIE0A;")?; writeln!(w, "}}")?; } @@ -300,14 +301,14 @@ mod gen { writeln!(w, " type ControlC = {};", find_reg_suffix("TCCR", "C").name)?; writeln!(w, " type InterruptMask = {};", find_reg("TIMSK").name)?; writeln!(w, " type InterruptFlag = {};", find_reg("TIFR").name)?; - writeln!(w, " const CS0: Mask = Self::ControlB::CS10;")?; - writeln!(w, " const CS1: Mask = Self::ControlB::CS11;")?; - writeln!(w, " const CS2: Mask = Self::ControlB::CS12;")?; - writeln!(w, " const WGM0: Mask = Self::ControlA::WGM10;")?; - writeln!(w, " const WGM1: Mask = Self::ControlA::WGM11;")?; - writeln!(w, " const WGM2: Mask = Self::ControlB::WGM10;")?; - writeln!(w, " const WGM3: Mask = Self::ControlB::WGM11;")?; - writeln!(w, " const OCIEA: Bitset = Self::InterruptMask::OCIE1A;")?; + writeln!(w, " const CS0: Mask = Self::ControlB::CS10;")?; + writeln!(w, " const CS1: Mask = Self::ControlB::CS11;")?; + writeln!(w, " const CS2: Mask = Self::ControlB::CS12;")?; + writeln!(w, " const WGM0: Mask = Self::ControlA::WGM10;")?; + writeln!(w, " const WGM1: Mask = Self::ControlA::WGM11;")?; + writeln!(w, " const WGM2: Mask = Self::ControlB::WGM10;")?; + writeln!(w, " const WGM3: Mask = Self::ControlB::WGM11;")?; + writeln!(w, " const OCIEA: Bitset = Self::InterruptMask::OCIE1A;")?; writeln!(w, "}}")?; } diff --git a/src/modules/spi/mod.rs b/src/modules/spi/mod.rs index 852b70e..64be15e 100644 --- a/src/modules/spi/mod.rs +++ b/src/modules/spi/mod.rs @@ -14,11 +14,11 @@ pub trait HardwareSpi { type SlaveSelect: Pin; /// The SPI control register. - type ControlRegister: Register; + type ControlRegister: Register; /// The SPI status register. - type StatusRegister: Register; + type StatusRegister: Register; /// The SPI data register. - type DataRegister: Register; + type DataRegister: Register; /// Sets up the SPI as a master. fn setup_master(clock: u32) { diff --git a/src/modules/timer/timer16.rs b/src/modules/timer/timer16.rs index 24456d8..a7dfcb4 100644 --- a/src/modules/timer/timer16.rs +++ b/src/modules/timer/timer16.rs @@ -2,57 +2,57 @@ use {Bitset, Mask, Register}; use core::marker; /// A 16-bit timer. -pub trait Timer16 { +pub trait Timer16 : Sized { /// The first compare register. /// For example, OCR0A. - type CompareA: Register; + type CompareA: Register; /// The second compare register. /// For example, OCR0B. - type CompareB: Register; + type CompareB: Register; /// The counter register. /// /// For example, TCNT0. - type Counter: Register; + type Counter: Register; /// The first control register. /// /// For example, TCCR0A. - type ControlA: Register; + type ControlA: Register; /// The second control register. /// /// For example, TCCR0B. - type ControlB: Register; + type ControlB: Register; /// The third control register. /// /// For example, TCCR0C. - type ControlC: Register; + type ControlC: Register; /// The interrupt mask register. /// /// For example, TIMSK0. - type InterruptMask: Register; + type InterruptMask: Register; /// The interrupt flag register. /// /// For example, TIFR0. - type InterruptFlag: Register; + type InterruptFlag: Register; - const CS0: Mask; - const CS1: Mask; - const CS2: Mask; + const CS0: Mask; + const CS1: Mask; + const CS2: Mask; - const WGM0: Mask; - const WGM1: Mask; - const WGM2: Mask; - const WGM3: Mask; + const WGM0: Mask; + const WGM1: Mask; + const WGM2: Mask; + const WGM3: Mask; - const OCIEA: Bitset; + const OCIEA: Bitset; - fn setup() -> Timer16Setup { Timer16Setup::new() } + fn setup() -> Timer16Setup { Timer16Setup::new() } } pub enum ClockSource { @@ -67,7 +67,7 @@ pub enum ClockSource { } impl ClockSource { - fn bits(&self) -> Mask { + fn bits(&self) -> Mask { use self::ClockSource::*; match *self { @@ -83,7 +83,7 @@ impl ClockSource { } #[inline] - fn mask() -> Mask { + fn mask() -> Mask { !(T::CS2 | T::CS1 | T::CS0) } } @@ -109,7 +109,7 @@ pub enum WaveformGenerationMode { impl WaveformGenerationMode { /// Returns bits for TCCR1A, TCCR1B #[inline] - fn bits(&self) -> (Mask, Mask) { + fn bits(&self) -> (Mask, Mask) { use self::WaveformGenerationMode::*; // It makes more sense to return bytes (A,B), but the manual @@ -139,15 +139,15 @@ impl WaveformGenerationMode { } #[inline] - fn mask() -> (Mask, Mask) { + fn mask() -> (Mask, Mask) { (!(T::WGM0 | T::WGM1), !(T::WGM2 | T::WGM3)) } } pub struct Timer16Setup { - a: Mask, - b: Mask, - c: Mask, + a: Mask, + b: Mask, + c: Mask, output_compare_1: Option, _phantom: marker::PhantomData, } diff --git a/src/modules/timer/timer8.rs b/src/modules/timer/timer8.rs index 4da6603..e2c2e2e 100644 --- a/src/modules/timer/timer8.rs +++ b/src/modules/timer/timer8.rs @@ -2,49 +2,49 @@ use {Bitset, Mask, Register}; use core::marker; /// A 8-bit timer. -pub trait Timer8 { +pub trait Timer8 : Sized { /// The first compare register. /// For example, OCR0A. - type CompareA: Register; + type CompareA: Register; /// The second compare register. /// For example, OCR0B. - type CompareB: Register; + type CompareB: Register; /// The counter register. /// /// For example, TCNT0. - type Counter: Register; + type Counter: Register; /// The first control register. /// /// For example, TCCR0A. - type ControlA: Register; + type ControlA: Register; /// The second control register. /// /// For example, TCCR0B. - type ControlB: Register; + type ControlB: Register; /// The interrupt mask register. /// /// For example, TIMSK0. - type InterruptMask: Register; + type InterruptMask: Register; /// The interrupt flag register. /// /// For example, TIFR0. - type InterruptFlag: Register; + type InterruptFlag: Register; - const CS0: Mask; - const CS1: Mask; - const CS2: Mask; + const CS0: Mask; + const CS1: Mask; + const CS2: Mask; - const WGM0: Mask; - const WGM1: Mask; - const WGM2: Mask; + const WGM0: Mask; + const WGM1: Mask; + const WGM2: Mask; - const OCIEA: Bitset; + const OCIEA: Bitset; } pub enum ClockSource { @@ -59,7 +59,7 @@ pub enum ClockSource { } impl ClockSource { - fn bits(&self) -> Mask { + fn bits(&self) -> Mask { use self::ClockSource::*; match *self { @@ -75,7 +75,7 @@ impl ClockSource { } #[inline] - fn mask() -> Mask { + fn mask() -> Mask { !(T::CS2 | T::CS1 | T::CS0) } } @@ -92,7 +92,7 @@ pub enum WaveformGenerationMode { impl WaveformGenerationMode { /// Returns bits for TCCR0A, TCCR0B #[inline] - fn bits(&self) -> (Mask, Mask) { + fn bits(&self) -> (Mask, Mask) { use self::WaveformGenerationMode::*; // It makes more sense to return bytes (A,B), but the manual @@ -114,14 +114,14 @@ impl WaveformGenerationMode { } #[inline] - fn mask() -> (Mask, Mask) { + fn mask() -> (Mask, Mask) { (!(T::WGM0 | T::WGM1), !(T::WGM2)) } } pub struct Timer8Setup { - a: Mask, - b: Mask, + a: Mask, + b: Mask, output_compare_1: Option, _phantom: marker::PhantomData, } diff --git a/src/modules/usart.rs b/src/modules/usart.rs index 995b953..7e8bc77 100644 --- a/src/modules/usart.rs +++ b/src/modules/usart.rs @@ -2,13 +2,13 @@ use Register; pub trait HardwareUsart { /// The USART data register. - type DataRegister: Register; + type DataRegister: Register; /// USART control and status register A. - type ControlRegisterA: Register; + type ControlRegisterA: Register; /// USART control and status register B. - type ControlRegisterB: Register; + type ControlRegisterB: Register; /// USART control and status register C. - type ControlRegisterC: Register; + type ControlRegisterC: Register; /// USART baud rate register. - type BaudRateRegister: Register; + type BaudRateRegister: Register; } diff --git a/src/pin.rs b/src/pin.rs index b23b2f1..758b89e 100644 --- a/src/pin.rs +++ b/src/pin.rs @@ -3,14 +3,14 @@ use {DataDirection, Register}; /// An IO pin. pub trait Pin { /// The associated data direction register. - type DDR: Register; + type DDR: Register; /// The associated port register. - type PORT: Register; + type PORT: Register; /// The associated pin register. /// /// Reads from the register will read input bits. /// Writes to the register will toggle bits. - type PIN: Register; + type PIN: Register; /// The mask of the pin used for accessing registers. const MASK: u8; diff --git a/src/register.rs b/src/register.rs index c543e96..6442188 100644 --- a/src/register.rs +++ b/src/register.rs @@ -14,15 +14,16 @@ pub trait RegisterValue : Copy + Clone + } /// A register. -pub trait Register : Sized { - type Mask = Mask; +pub trait Register : Sized { + type T: RegisterValue; + type Mask = Mask; /// The address of the register. - const ADDR: *mut T; + const ADDR: *mut Self::T; /// Writes a value to the register. #[inline(always)] - fn write(value: V) where V: Into { + fn write(value: V) where V: Into { unsafe { *Self::ADDR = value.into(); } @@ -30,11 +31,11 @@ pub trait Register : Sized { /// Reads the value of the register. #[inline(always)] - fn read() -> T { + fn read() -> Self::T { unsafe { *Self::ADDR } } - fn set(mask: Mask) { + fn set(mask: Mask) { Self::set_raw(mask.mask); } @@ -42,13 +43,13 @@ pub trait Register : Sized { /// /// This is equivalent to `r |= mask`. #[inline(always)] - fn set_raw(mask: T) { + fn set_raw(mask: Self::T) { unsafe { *Self::ADDR |= mask; } } - fn unset(mask: Mask) { + fn unset(mask: Mask) { Self::unset_raw(mask.mask); } @@ -56,13 +57,13 @@ pub trait Register : Sized { /// /// This is equivalent to `r &= !mask`. #[inline(always)] - fn unset_raw(mask: T) { + fn unset_raw(mask: Self::T) { unsafe { *Self::ADDR &= !mask; } } - fn toggle(mask: Mask) { + fn toggle(mask: Mask) { Self::toggle_raw(mask.mask); } @@ -70,13 +71,13 @@ pub trait Register : Sized { /// /// This is equivalent to `r ^= mask`. #[inline(always)] - fn toggle_raw(mask: T) { + fn toggle_raw(mask: Self::T) { unsafe { *Self::ADDR ^= mask; } } - fn is_set(mask: Mask) -> bool { + fn is_set(mask: Mask) -> bool { Self::is_set_raw(mask.mask) } @@ -84,13 +85,13 @@ pub trait Register : Sized { /// /// This is equivalent to `(r & mask) == mask`. #[inline(always)] - fn is_set_raw(mask: T) -> bool { + fn is_set_raw(mask: Self::T) -> bool { unsafe { (*Self::ADDR & mask) == mask } } - fn is_clear(mask: Mask) -> bool { + fn is_clear(mask: Mask) -> bool { Self::is_clear_raw(mask.mask) } @@ -98,9 +99,9 @@ pub trait Register : Sized { /// /// This is equivalent to `(r & mask) == 0`. #[inline(always)] - fn is_clear_raw(mask: T) -> bool { + fn is_clear_raw(mask: Self::T) -> bool { unsafe { - (*Self::ADDR & mask) == T::from(0) + (*Self::ADDR & mask) == Self::T::from(0) } } @@ -115,35 +116,34 @@ pub trait Register : Sized { } } - fn wait_until_set(mask: Mask) { + fn wait_until_set(mask: Mask) { Self::wait_until_set_raw(mask.mask); } /// Waits until a mask is set. #[inline(always)] - fn wait_until_set_raw(mask: T) { + fn wait_until_set_raw(mask: Self::T) { Self::wait_until(|| Self::is_set_raw(mask)) } } /// A register bitmask. #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct Bitset> { - mask: T, +pub struct Bitset { + mask: R::T, _phantom: marker::PhantomData, } /// A register bitmask. #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct Mask> { - mask: T, +pub struct Mask { + mask: R::T, _phantom: marker::PhantomData, } -impl Bitset - where T: RegisterValue, R: Register { +impl Bitset where R: Register { /// Creates a new register mask. - pub const fn new(mask: T) -> Self { + pub const fn new(mask: R::T) -> Self { Bitset { mask, _phantom: marker::PhantomData } } @@ -176,10 +176,9 @@ impl Bitset } } -impl Mask - where T: RegisterValue, R: Register { +impl Mask where R: Register { /// Creates a new register mask. - pub const fn new(mask: T) -> Self { + pub const fn new(mask: R::T) -> Self { Mask { mask, _phantom: marker::PhantomData } } @@ -188,8 +187,7 @@ impl Mask } } -impl ops::BitOr for Mask - where T: RegisterValue, R: Register +impl ops::BitOr for Mask where R: Register { type Output = Self; @@ -198,15 +196,13 @@ impl ops::BitOr for Mask } } -impl ops::BitOrAssign for Mask - where T: RegisterValue, R: Register { +impl ops::BitOrAssign for Mask where R: Register { fn bitor_assign(&mut self, rhs: Self) { self.mask |= rhs.mask; } } -impl ops::BitAnd for Mask - where T: RegisterValue, R: Register +impl ops::BitAnd for Mask where R: Register { type Output = Self; @@ -215,15 +211,13 @@ impl ops::BitAnd for Mask } } -impl ops::BitAndAssign for Mask - where T: RegisterValue, R: Register { +impl ops::BitAndAssign for Mask where R: Register { fn bitand_assign(&mut self, rhs: Self) { self.mask &= rhs.mask; } } -impl ops::Not for Mask - where T: RegisterValue, R: Register { +impl ops::Not for Mask where R: Register { type Output = Self; fn not(self) -> Self { @@ -231,10 +225,12 @@ impl ops::Not for Mask } } -impl Into for Mask where R: Register { - fn into(self) -> u8 { - self.mask - } +impl Into for Mask where R: Register { + fn into(self) -> u8 { self.mask } +} + +impl Into for Mask where R: Register { + fn into(self) -> u16 { self.mask } } impl RegisterValue for u8 { }