parent
f90d5b2d0b
commit
aecd4edb36
|
@ -52,6 +52,7 @@ fn generate_config_module() -> Result<(), io::Error> {
|
||||||
let mut f = File::create(&path)?;
|
let mut f = File::create(&path)?;
|
||||||
|
|
||||||
let clock = env!("AVR_CPU_FREQUENCY_HZ");
|
let clock = env!("AVR_CPU_FREQUENCY_HZ");
|
||||||
|
writeln!(f, "/// The clock frequency of device being targeted in Hertz.")?;
|
||||||
writeln!(f, "pub const CPU_FREQUENCY_HZ: u32 = {};", clock)?;
|
writeln!(f, "pub const CPU_FREQUENCY_HZ: u32 = {};", clock)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -81,7 +82,7 @@ fn generate_cores_mod_rs(mcus: &[Mcu]) -> Result<(), io::Error> {
|
||||||
fn write_core_module(mcu: &Mcu, w: &mut Write) -> Result<(), io::Error> {
|
fn write_core_module(mcu: &Mcu, w: &mut Write) -> Result<(), io::Error> {
|
||||||
writeln!(w, "//! Core for {}.", mcu.device.name)?;
|
writeln!(w, "//! Core for {}.", mcu.device.name)?;
|
||||||
writeln!(w)?;
|
writeln!(w)?;
|
||||||
writeln!(w, "use {{Mask, Register}};")?;
|
writeln!(w, "use {{RegisterBits, Register}};")?;
|
||||||
writeln!(w, "use modules;")?;
|
writeln!(w, "use modules;")?;
|
||||||
writeln!(w)?;
|
writeln!(w)?;
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ pub fn write_registers(mcu: &Mcu, w: &mut Write) -> Result<(), io::Error> {
|
||||||
writeln!(w, "impl {} {{", register.name)?;
|
writeln!(w, "impl {} {{", register.name)?;
|
||||||
for bitfield in register.bitfields.iter() {
|
for bitfield in register.bitfields.iter() {
|
||||||
// Create a mask for the whole bitset.
|
// Create a mask for the whole bitset.
|
||||||
writeln!(w, " pub const {}: Mask<Self> = Mask::new(0x{:x});", bitfield.name, bitfield.mask)?;
|
writeln!(w, " pub const {}: RegisterBits<Self> = RegisterBits::new(0x{:x});", bitfield.name, bitfield.mask)?;
|
||||||
|
|
||||||
// We create masks for the individual bits in the field if there
|
// We create masks for the individual bits in the field if there
|
||||||
// is more than one bit in the field.
|
// is more than one bit in the field.
|
||||||
|
@ -23,7 +23,7 @@ pub fn write_registers(mcu: &Mcu, w: &mut Write) -> Result<(), io::Error> {
|
||||||
let mut current_mask_bit_num = 0;
|
let mut current_mask_bit_num = 0;
|
||||||
for current_register_bit_num in 0..15 {
|
for current_register_bit_num in 0..15 {
|
||||||
if (current_mask & 0b1) == 0b1 {
|
if (current_mask & 0b1) == 0b1 {
|
||||||
writeln!(w, " pub const {}{}: Mask<Self> = Mask::new(1<<{});",
|
writeln!(w, " pub const {}{}: RegisterBits<Self> = RegisterBits::new(1<<{});",
|
||||||
bitfield.name, current_mask_bit_num, current_register_bit_num)?;
|
bitfield.name, current_mask_bit_num, current_register_bit_num)?;
|
||||||
current_mask_bit_num += 1;
|
current_mask_bit_num += 1;
|
||||||
}
|
}
|
||||||
|
@ -182,13 +182,13 @@ pub fn write_timers(mcu: &Mcu, w: &mut Write) -> Result<(), io::Error> {
|
||||||
writeln!(w, " type ControlB = {};", find_reg_suffix("TCCR", "B").name)?;
|
writeln!(w, " type ControlB = {};", find_reg_suffix("TCCR", "B").name)?;
|
||||||
writeln!(w, " type InterruptMask = {};", find_reg("TIMSK").name)?;
|
writeln!(w, " type InterruptMask = {};", find_reg("TIMSK").name)?;
|
||||||
writeln!(w, " type InterruptFlag = {};", find_reg("TIFR").name)?;
|
writeln!(w, " type InterruptFlag = {};", find_reg("TIFR").name)?;
|
||||||
writeln!(w, " const CS0: Mask<Self::ControlB> = Self::ControlB::CS00;")?;
|
writeln!(w, " const CS0: RegisterBits<Self::ControlB> = Self::ControlB::CS00;")?;
|
||||||
writeln!(w, " const CS1: Mask<Self::ControlB> = Self::ControlB::CS01;")?;
|
writeln!(w, " const CS1: RegisterBits<Self::ControlB> = Self::ControlB::CS01;")?;
|
||||||
writeln!(w, " const CS2: Mask<Self::ControlB> = Self::ControlB::CS02;")?;
|
writeln!(w, " const CS2: RegisterBits<Self::ControlB> = Self::ControlB::CS02;")?;
|
||||||
writeln!(w, " const WGM0: Mask<Self::ControlA> = Self::ControlA::WGM00;")?;
|
writeln!(w, " const WGM0: RegisterBits<Self::ControlA> = Self::ControlA::WGM00;")?;
|
||||||
writeln!(w, " const WGM1: Mask<Self::ControlA> = Self::ControlA::WGM01;")?;
|
writeln!(w, " const WGM1: RegisterBits<Self::ControlA> = Self::ControlA::WGM01;")?;
|
||||||
writeln!(w, " const WGM2: Mask<Self::ControlB> = Self::ControlB::WGM020;")?;
|
writeln!(w, " const WGM2: RegisterBits<Self::ControlB> = Self::ControlB::WGM020;")?;
|
||||||
writeln!(w, " const OCIEA: Mask<Self::InterruptMask> = Self::InterruptMask::OCIE{}A;", timer_number)?;
|
writeln!(w, " const OCIEA: RegisterBits<Self::InterruptMask> = Self::InterruptMask::OCIE{}A;", timer_number)?;
|
||||||
writeln!(w, "}}")?;
|
writeln!(w, "}}")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,14 +218,14 @@ pub fn write_timers(mcu: &Mcu, w: &mut Write) -> Result<(), io::Error> {
|
||||||
writeln!(w, " type ControlC = {};", find_reg_suffix("TCCR", "C").name)?;
|
writeln!(w, " type ControlC = {};", find_reg_suffix("TCCR", "C").name)?;
|
||||||
writeln!(w, " type InterruptMask = {};", find_reg("TIMSK").name)?;
|
writeln!(w, " type InterruptMask = {};", find_reg("TIMSK").name)?;
|
||||||
writeln!(w, " type InterruptFlag = {};", find_reg("TIFR").name)?;
|
writeln!(w, " type InterruptFlag = {};", find_reg("TIFR").name)?;
|
||||||
writeln!(w, " const CS0: Mask<Self::ControlB> = Self::ControlB::CS10;")?;
|
writeln!(w, " const CS0: RegisterBits<Self::ControlB> = Self::ControlB::CS10;")?;
|
||||||
writeln!(w, " const CS1: Mask<Self::ControlB> = Self::ControlB::CS11;")?;
|
writeln!(w, " const CS1: RegisterBits<Self::ControlB> = Self::ControlB::CS11;")?;
|
||||||
writeln!(w, " const CS2: Mask<Self::ControlB> = Self::ControlB::CS12;")?;
|
writeln!(w, " const CS2: RegisterBits<Self::ControlB> = Self::ControlB::CS12;")?;
|
||||||
writeln!(w, " const WGM0: Mask<Self::ControlA> = Self::ControlA::WGM10;")?;
|
writeln!(w, " const WGM0: RegisterBits<Self::ControlA> = Self::ControlA::WGM10;")?;
|
||||||
writeln!(w, " const WGM1: Mask<Self::ControlA> = Self::ControlA::WGM11;")?;
|
writeln!(w, " const WGM1: RegisterBits<Self::ControlA> = Self::ControlA::WGM11;")?;
|
||||||
writeln!(w, " const WGM2: Mask<Self::ControlB> = Self::ControlB::WGM10;")?;
|
writeln!(w, " const WGM2: RegisterBits<Self::ControlB> = Self::ControlB::WGM10;")?;
|
||||||
writeln!(w, " const WGM3: Mask<Self::ControlB> = Self::ControlB::WGM11;")?;
|
writeln!(w, " const WGM3: RegisterBits<Self::ControlB> = Self::ControlB::WGM11;")?;
|
||||||
writeln!(w, " const OCIEA: Mask<Self::InterruptMask> = Self::InterruptMask::OCIE{}A;", timer_number)?;
|
writeln!(w, " const OCIEA: RegisterBits<Self::InterruptMask> = Self::InterruptMask::OCIE{}A;", timer_number)?;
|
||||||
writeln!(w, "}}")?;
|
writeln!(w, "}}")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
pub use self::register::{Mask, Register, RegisterValue};
|
pub use self::register::{Register, RegisterBits, RegisterValue};
|
||||||
pub use self::pin::{DataDirection, Pin};
|
pub use self::pin::{DataDirection, Pin};
|
||||||
|
|
||||||
pub mod prelude;
|
pub mod prelude;
|
||||||
|
|
|
@ -56,87 +56,87 @@ pub trait HardwareSpi {
|
||||||
/// Sets the clock speed.
|
/// Sets the clock speed.
|
||||||
fn set_clock(clock: u32) {
|
fn set_clock(clock: u32) {
|
||||||
let mask = clock::ClockMask::with_clock(clock);
|
let mask = clock::ClockMask::with_clock(clock);
|
||||||
Self::ControlRegister::set_raw(mask.control_register_mask());
|
Self::ControlRegister::set_mask_raw(mask.control_register_mask());
|
||||||
Self::StatusRegister::set_raw(mask.status_register_mask());
|
Self::StatusRegister::set_mask_raw(mask.status_register_mask());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enables interrupts for the spi module.
|
/// Enables interrupts for the spi module.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn enable_interrupt() {
|
fn enable_interrupt() {
|
||||||
Self::ControlRegister::set_raw(settings::control_register::INTERRUPT_ENABLE);
|
Self::ControlRegister::set_mask_raw(settings::control_register::INTERRUPT_ENABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Disables interrupts for the spi module.
|
/// Disables interrupts for the spi module.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn disable_interrupt() {
|
fn disable_interrupt() {
|
||||||
Self::ControlRegister::unset_raw(settings::control_register::INTERRUPT_ENABLE);
|
Self::ControlRegister::unset_mask_raw(settings::control_register::INTERRUPT_ENABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enables the SPI.
|
/// Enables the SPI.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn enable() {
|
fn enable() {
|
||||||
Self::ControlRegister::set_raw(settings::control_register::ENABLE);
|
Self::ControlRegister::set_mask_raw(settings::control_register::ENABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Disables the SPI.
|
/// Disables the SPI.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn disable() {
|
fn disable() {
|
||||||
Self::ControlRegister::unset_raw(settings::control_register::ENABLE);
|
Self::ControlRegister::unset_mask_raw(settings::control_register::ENABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enables least-significant-bit first.
|
/// Enables least-significant-bit first.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn set_lsb() {
|
fn set_lsb() {
|
||||||
Self::ControlRegister::set_raw(settings::control_register::DATA_ORDER_LSB);
|
Self::ControlRegister::set_mask_raw(settings::control_register::DATA_ORDER_LSB);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enables most-significant-bit first.
|
/// Enables most-significant-bit first.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn set_msb() {
|
fn set_msb() {
|
||||||
Self::ControlRegister::unset_raw(settings::control_register::DATA_ORDER_LSB);
|
Self::ControlRegister::unset_mask_raw(settings::control_register::DATA_ORDER_LSB);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enables master mode.
|
/// Enables master mode.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn set_master() {
|
fn set_master() {
|
||||||
Self::ControlRegister::set_raw(settings::control_register::MASTER);
|
Self::ControlRegister::set_mask_raw(settings::control_register::MASTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enables slave mode.
|
/// Enables slave mode.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn set_slave() {
|
fn set_slave() {
|
||||||
Self::ControlRegister::unset_raw(settings::control_register::MASTER);
|
Self::ControlRegister::unset_mask_raw(settings::control_register::MASTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enables double speed mode.
|
/// Enables double speed mode.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn enable_double_speed() {
|
fn enable_double_speed() {
|
||||||
Self::StatusRegister::set_raw(settings::status_register::SPI2X);
|
Self::StatusRegister::set_mask_raw(settings::status_register::SPI2X);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Disables double speed mode.
|
/// Disables double speed mode.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn disable_double_speed() {
|
fn disable_double_speed() {
|
||||||
Self::StatusRegister::unset_raw(settings::status_register::SPI2X);
|
Self::StatusRegister::unset_mask_raw(settings::status_register::SPI2X);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks if there is a write collision.
|
/// Checks if there is a write collision.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn is_write_collision() -> bool {
|
fn is_write_collision() -> bool {
|
||||||
Self::StatusRegister::is_set_raw(settings::status_register::WCOL)
|
Self::StatusRegister::is_mask_set_raw(settings::status_register::WCOL)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sends a byte through the serial.
|
/// Sends a byte through the serial.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn send_byte(byte: u8) {
|
fn send_byte(byte: u8) {
|
||||||
Self::DataRegister::write(byte);
|
Self::DataRegister::write(byte);
|
||||||
Self::StatusRegister::wait_until_set_raw(settings::status_register::SPIF);
|
Self::StatusRegister::wait_until_mask_set_raw(settings::status_register::SPIF);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reads a byte from the serial.
|
/// Reads a byte from the serial.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn receive_byte() -> u8 {
|
fn receive_byte() -> u8 {
|
||||||
Self::StatusRegister::wait_until_set_raw(settings::status_register::SPIF);
|
Self::StatusRegister::wait_until_mask_set_raw(settings::status_register::SPIF);
|
||||||
Self::DataRegister::read()
|
Self::DataRegister::read()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,7 +144,7 @@ pub trait HardwareSpi {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn send_receive(byte: u8) -> u8 {
|
fn send_receive(byte: u8) -> u8 {
|
||||||
Self::DataRegister::write(byte);
|
Self::DataRegister::write(byte);
|
||||||
Self::StatusRegister::wait_until_set_raw(settings::status_register::SPIF);
|
Self::StatusRegister::wait_until_mask_set_raw(settings::status_register::SPIF);
|
||||||
Self::DataRegister::read()
|
Self::DataRegister::read()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use {Mask, Register};
|
use {RegisterBits, Register};
|
||||||
use core::marker;
|
use core::marker;
|
||||||
|
|
||||||
/// A 16-bit timer.
|
/// A 16-bit timer.
|
||||||
|
@ -41,16 +41,16 @@ pub trait Timer16 : Sized {
|
||||||
/// For example, TIFR0.
|
/// For example, TIFR0.
|
||||||
type InterruptFlag: Register<T=u8>;
|
type InterruptFlag: Register<T=u8>;
|
||||||
|
|
||||||
const CS0: Mask<Self::ControlB>;
|
const CS0: RegisterBits<Self::ControlB>;
|
||||||
const CS1: Mask<Self::ControlB>;
|
const CS1: RegisterBits<Self::ControlB>;
|
||||||
const CS2: Mask<Self::ControlB>;
|
const CS2: RegisterBits<Self::ControlB>;
|
||||||
|
|
||||||
const WGM0: Mask<Self::ControlA>;
|
const WGM0: RegisterBits<Self::ControlA>;
|
||||||
const WGM1: Mask<Self::ControlA>;
|
const WGM1: RegisterBits<Self::ControlA>;
|
||||||
const WGM2: Mask<Self::ControlB>;
|
const WGM2: RegisterBits<Self::ControlB>;
|
||||||
const WGM3: Mask<Self::ControlB>;
|
const WGM3: RegisterBits<Self::ControlB>;
|
||||||
|
|
||||||
const OCIEA: Mask<Self::InterruptMask>;
|
const OCIEA: RegisterBits<Self::InterruptMask>;
|
||||||
|
|
||||||
fn setup() -> Timer16Setup<Self> { Timer16Setup::new() }
|
fn setup() -> Timer16Setup<Self> { Timer16Setup::new() }
|
||||||
}
|
}
|
||||||
|
@ -67,23 +67,23 @@ pub enum ClockSource {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ClockSource {
|
impl ClockSource {
|
||||||
fn bits<T: Timer16>(&self) -> Mask<T::ControlB> {
|
fn bits<T: Timer16>(&self) -> RegisterBits<T::ControlB> {
|
||||||
use self::ClockSource::*;
|
use self::ClockSource::*;
|
||||||
|
|
||||||
match *self {
|
match *self {
|
||||||
None => Mask::zero() | Mask::zero() | Mask::zero(),
|
None => RegisterBits::zero() | RegisterBits::zero() | RegisterBits::zero(),
|
||||||
Prescale1 => Mask::zero() | Mask::zero() | T::CS0,
|
Prescale1 => RegisterBits::zero() | RegisterBits::zero() | T::CS0,
|
||||||
Prescale8 => Mask::zero() | T::CS1 | Mask::zero(),
|
Prescale8 => RegisterBits::zero() | T::CS1 | RegisterBits::zero(),
|
||||||
Prescale64 => Mask::zero() | T::CS1 | T::CS0,
|
Prescale64 => RegisterBits::zero() | T::CS1 | T::CS0,
|
||||||
Prescale256 => T::CS2 | Mask::zero() | Mask::zero(),
|
Prescale256 => T::CS2 | RegisterBits::zero() | RegisterBits::zero(),
|
||||||
Prescale1024 => T::CS2 | Mask::zero() | T::CS0,
|
Prescale1024 => T::CS2 | RegisterBits::zero() | T::CS0,
|
||||||
ExternalFalling => T::CS2 | T::CS1 | Mask::zero(),
|
ExternalFalling => T::CS2 | T::CS1 | RegisterBits::zero(),
|
||||||
ExternalRising => T::CS2 | T::CS1 | T::CS0,
|
ExternalRising => T::CS2 | T::CS1 | T::CS0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mask<T: Timer16>() -> Mask<T::ControlB> {
|
fn mask<T: Timer16>() -> RegisterBits<T::ControlB> {
|
||||||
!(T::CS2 | T::CS1 | T::CS0)
|
!(T::CS2 | T::CS1 | T::CS0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,29 +109,30 @@ pub enum WaveformGenerationMode {
|
||||||
impl WaveformGenerationMode {
|
impl WaveformGenerationMode {
|
||||||
/// Returns bits for TCCR1A, TCCR1B
|
/// Returns bits for TCCR1A, TCCR1B
|
||||||
#[inline]
|
#[inline]
|
||||||
fn bits<T: Timer16>(&self) -> (Mask<T::ControlA>, Mask<T::ControlB>) {
|
fn bits<T: Timer16>(&self) -> (RegisterBits<T::ControlA>, RegisterBits<T::ControlB>) {
|
||||||
use self::WaveformGenerationMode::*;
|
use self::WaveformGenerationMode::*;
|
||||||
|
use RegisterBits as B;
|
||||||
|
|
||||||
// It makes more sense to return bytes (A,B), but the manual
|
// It makes more sense to return bytes (A,B), but the manual
|
||||||
// lists the table as (B,A). We match the manual here for
|
// lists the table as (B,A). We match the manual here for
|
||||||
// inspection purposes and flip the values for sanity
|
// inspection purposes and flip the values for sanity
|
||||||
// purposes.
|
// purposes.
|
||||||
let (b, a) = match *self {
|
let (b, a) = match *self {
|
||||||
Normal => (Mask::zero() | Mask::zero(), Mask::zero() | Mask::zero()),
|
Normal => (B::zero() | B::zero(), B::zero() | B::zero()),
|
||||||
PwmPhaseCorrect8Bit => (Mask::zero() | Mask::zero(), Mask::zero() | T::WGM0),
|
PwmPhaseCorrect8Bit => (B::zero() | B::zero(), B::zero() | T::WGM0),
|
||||||
PwmPhaseCorrect9Bit => (Mask::zero() | Mask::zero(), T::WGM1 | Mask::zero()),
|
PwmPhaseCorrect9Bit => (B::zero() | B::zero(), T::WGM1 | B::zero()),
|
||||||
PwmPhaseCorrect10Bit => (Mask::zero() | Mask::zero(), T::WGM1 | T::WGM0),
|
PwmPhaseCorrect10Bit => (B::zero() | B::zero(), T::WGM1 | T::WGM0),
|
||||||
ClearOnTimerMatchOutputCompare => (Mask::zero() | T::WGM2, Mask::zero() | Mask::zero()),
|
ClearOnTimerMatchOutputCompare => (B::zero() | T::WGM2, B::zero() | B::zero()),
|
||||||
FastPwm8Bit => (Mask::zero() | T::WGM2, Mask::zero() | T::WGM0),
|
FastPwm8Bit => (B::zero() | T::WGM2, B::zero() | T::WGM0),
|
||||||
FastPwm9Bit => (Mask::zero() | T::WGM2, T::WGM1 | Mask::zero()),
|
FastPwm9Bit => (B::zero() | T::WGM2, T::WGM1 | B::zero()),
|
||||||
FastPwm10Bit => (Mask::zero() | T::WGM2, T::WGM1 | T::WGM0),
|
FastPwm10Bit => (B::zero() | T::WGM2, T::WGM1 | T::WGM0),
|
||||||
PwmPhaseAndFrequencyCorrectInputCapture => (T::WGM3 | Mask::zero(), Mask::zero() | Mask::zero()),
|
PwmPhaseAndFrequencyCorrectInputCapture => (T::WGM3 | B::zero(), B::zero() | B::zero()),
|
||||||
PwmPhaseAndFrequencyCorrectOutputCompare => (T::WGM3 | Mask::zero(), Mask::zero() | T::WGM0),
|
PwmPhaseAndFrequencyCorrectOutputCompare => (T::WGM3 | B::zero(), B::zero() | T::WGM0),
|
||||||
PwmPhaseCorrectInputCapture => (T::WGM3 | Mask::zero(), T::WGM1 | Mask::zero()),
|
PwmPhaseCorrectInputCapture => (T::WGM3 | B::zero(), T::WGM1 | B::zero()),
|
||||||
PwmPhaseCorrectOutputCompare => (T::WGM3 | Mask::zero(), T::WGM1 | T::WGM0),
|
PwmPhaseCorrectOutputCompare => (T::WGM3 | B::zero(), T::WGM1 | T::WGM0),
|
||||||
ClearOnTimerMatchInputCapture => (T::WGM3 | T::WGM2, Mask::zero() | Mask::zero()),
|
ClearOnTimerMatchInputCapture => (T::WGM3 | T::WGM2, B::zero() | B::zero()),
|
||||||
// Reserved => (T::WGM3 | T::WGM2, Mask::zero() | T::WGM0),
|
// Reserved => (T::WGM3 | T::WGM2, B::zero() | T::WGM0),
|
||||||
FastPwmInputCapture => (T::WGM3 | T::WGM2, T::WGM1 | Mask::zero()),
|
FastPwmInputCapture => (T::WGM3 | T::WGM2, T::WGM1 | B::zero()),
|
||||||
FastPwmOutputCompare => (T::WGM3 | T::WGM2, T::WGM1 | T::WGM0),
|
FastPwmOutputCompare => (T::WGM3 | T::WGM2, T::WGM1 | T::WGM0),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -139,15 +140,15 @@ impl WaveformGenerationMode {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mask<T: Timer16>() -> (Mask<T::ControlA>, Mask<T::ControlB>) {
|
fn mask<T: Timer16>() -> (RegisterBits<T::ControlA>, RegisterBits<T::ControlB>) {
|
||||||
(!(T::WGM0 | T::WGM1), !(T::WGM2 | T::WGM3))
|
(!(T::WGM0 | T::WGM1), !(T::WGM2 | T::WGM3))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Timer16Setup<T: Timer16> {
|
pub struct Timer16Setup<T: Timer16> {
|
||||||
a: Mask<T::ControlA>,
|
a: RegisterBits<T::ControlA>,
|
||||||
b: Mask<T::ControlB>,
|
b: RegisterBits<T::ControlB>,
|
||||||
c: Mask<T::ControlC>,
|
c: RegisterBits<T::ControlC>,
|
||||||
output_compare_1: Option<u16>,
|
output_compare_1: Option<u16>,
|
||||||
_phantom: marker::PhantomData<T>,
|
_phantom: marker::PhantomData<T>,
|
||||||
}
|
}
|
||||||
|
@ -156,9 +157,9 @@ impl<T: Timer16> Timer16Setup<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
Timer16Setup {
|
Timer16Setup {
|
||||||
a: Mask::zero(),
|
a: RegisterBits::zero(),
|
||||||
b: Mask::zero(),
|
b: RegisterBits::zero(),
|
||||||
c: Mask::zero(),
|
c: RegisterBits::zero(),
|
||||||
output_compare_1: None,
|
output_compare_1: None,
|
||||||
_phantom: marker::PhantomData,
|
_phantom: marker::PhantomData,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use {Mask, Register};
|
use {RegisterBits, Register};
|
||||||
use core::marker;
|
use core::marker;
|
||||||
|
|
||||||
/// A 8-bit timer.
|
/// A 8-bit timer.
|
||||||
|
@ -37,21 +37,21 @@ pub trait Timer8 : Sized {
|
||||||
type InterruptFlag: Register<T=u8>;
|
type InterruptFlag: Register<T=u8>;
|
||||||
|
|
||||||
/// Bit 0 of the clock select mask.
|
/// Bit 0 of the clock select mask.
|
||||||
const CS0: Mask<Self::ControlB>;
|
const CS0: RegisterBits<Self::ControlB>;
|
||||||
/// Bit 1 of the clock select mask.
|
/// Bit 1 of the clock select mask.
|
||||||
const CS1: Mask<Self::ControlB>;
|
const CS1: RegisterBits<Self::ControlB>;
|
||||||
/// Bit 2 of the clock select mask.
|
/// Bit 2 of the clock select mask.
|
||||||
const CS2: Mask<Self::ControlB>;
|
const CS2: RegisterBits<Self::ControlB>;
|
||||||
|
|
||||||
/// Bit 0 of the waveform generation mode mask.
|
/// Bit 0 of the waveform generation mode mask.
|
||||||
const WGM0: Mask<Self::ControlA>;
|
const WGM0: RegisterBits<Self::ControlA>;
|
||||||
/// Bit 1 of the waveform generation mode mask.
|
/// Bit 1 of the waveform generation mode mask.
|
||||||
const WGM1: Mask<Self::ControlA>;
|
const WGM1: RegisterBits<Self::ControlA>;
|
||||||
/// Bit 2 of the waveform generation mode mask.
|
/// Bit 2 of the waveform generation mode mask.
|
||||||
const WGM2: Mask<Self::ControlB>;
|
const WGM2: RegisterBits<Self::ControlB>;
|
||||||
|
|
||||||
/// Output compare interrupt enable flag.
|
/// Output compare interrupt enable flag.
|
||||||
const OCIEA: Mask<Self::InterruptMask>;
|
const OCIEA: RegisterBits<Self::InterruptMask>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum ClockSource {
|
pub enum ClockSource {
|
||||||
|
@ -66,23 +66,23 @@ pub enum ClockSource {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ClockSource {
|
impl ClockSource {
|
||||||
fn bits<T: Timer8>(&self) -> Mask<T::ControlB> {
|
fn bits<T: Timer8>(&self) -> RegisterBits<T::ControlB> {
|
||||||
use self::ClockSource::*;
|
use self::ClockSource::*;
|
||||||
|
|
||||||
match *self {
|
match *self {
|
||||||
None => Mask::zero() | Mask::zero() | Mask::zero(),
|
None => RegisterBits::zero() | RegisterBits::zero() | RegisterBits::zero(),
|
||||||
Prescale1 => Mask::zero() | Mask::zero() | T::CS0,
|
Prescale1 => RegisterBits::zero() | RegisterBits::zero() | T::CS0,
|
||||||
Prescale8 => Mask::zero() | T::CS1 | Mask::zero(),
|
Prescale8 => RegisterBits::zero() | T::CS1 | RegisterBits::zero(),
|
||||||
Prescale64 => Mask::zero() | T::CS1 | T::CS0,
|
Prescale64 => RegisterBits::zero() | T::CS1 | T::CS0,
|
||||||
Prescale256 => T::CS2 | Mask::zero() | Mask::zero(),
|
Prescale256 => T::CS2 | RegisterBits::zero() | RegisterBits::zero(),
|
||||||
Prescale1024 => T::CS2 | Mask::zero() | T::CS0,
|
Prescale1024 => T::CS2 | RegisterBits::zero() | T::CS0,
|
||||||
ExternalFalling => T::CS2 | T::CS1 | Mask::zero(),
|
ExternalFalling => T::CS2 | T::CS1 | RegisterBits::zero(),
|
||||||
ExternalRising => T::CS2 | T::CS1 | T::CS0,
|
ExternalRising => T::CS2 | T::CS1 | T::CS0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mask<T: Timer8>() -> Mask<T::ControlB> {
|
fn mask<T: Timer8>() -> RegisterBits<T::ControlB> {
|
||||||
!(T::CS2 | T::CS1 | T::CS0)
|
!(T::CS2 | T::CS1 | T::CS0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,7 @@ pub enum WaveformGenerationMode {
|
||||||
impl WaveformGenerationMode {
|
impl WaveformGenerationMode {
|
||||||
/// Returns bits for TCCR0A, TCCR0B
|
/// Returns bits for TCCR0A, TCCR0B
|
||||||
#[inline]
|
#[inline]
|
||||||
fn bits<T: Timer8>(&self) -> (Mask<T::ControlA>, Mask<T::ControlB>) {
|
fn bits<T: Timer8>(&self) -> (RegisterBits<T::ControlA>, RegisterBits<T::ControlB>) {
|
||||||
use self::WaveformGenerationMode::*;
|
use self::WaveformGenerationMode::*;
|
||||||
|
|
||||||
// It makes more sense to return bytes (A,B), but the manual
|
// It makes more sense to return bytes (A,B), but the manual
|
||||||
|
@ -107,13 +107,13 @@ impl WaveformGenerationMode {
|
||||||
// inspection purposes and flip the values for sanity
|
// inspection purposes and flip the values for sanity
|
||||||
// purposes.
|
// purposes.
|
||||||
let (b, a) = match *self {
|
let (b, a) = match *self {
|
||||||
Normal => (Mask::zero(), Mask::zero() | Mask::zero()),
|
Normal => (RegisterBits::zero(), RegisterBits::zero() | RegisterBits::zero()),
|
||||||
PwmPhaseCorrect => (Mask::zero(), Mask::zero() | T::WGM0),
|
PwmPhaseCorrect => (RegisterBits::zero(), RegisterBits::zero() | T::WGM0),
|
||||||
ClearOnTimerMatchOutputCompare => (Mask::zero(), T::WGM1 | Mask::zero()),
|
ClearOnTimerMatchOutputCompare => (RegisterBits::zero(), T::WGM1 | RegisterBits::zero()),
|
||||||
FastPwm => (Mask::zero(), T::WGM1 | T::WGM0),
|
FastPwm => (RegisterBits::zero(), T::WGM1 | T::WGM0),
|
||||||
// Reserved => (T::WGM2, Mask::zero() | Mask::zero()),
|
// Reserved => (T::WGM2, RegisterBits::zero() | RegisterBits::zero()),
|
||||||
PwmPhaseCorrectOutputCompare => (T::WGM2, Mask::zero() | T::WGM0),
|
PwmPhaseCorrectOutputCompare => (T::WGM2, RegisterBits::zero() | T::WGM0),
|
||||||
// Reserved => (T::WGM2, T::WGM1 | Mask::zero())),
|
// Reserved => (T::WGM2, T::WGM1 | RegisterBits::zero())),
|
||||||
FastPwmOutputCompare => (T::WGM2, T::WGM1 | T::WGM0),
|
FastPwmOutputCompare => (T::WGM2, T::WGM1 | T::WGM0),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -121,14 +121,14 @@ impl WaveformGenerationMode {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mask<T: Timer8>() -> (Mask<T::ControlA>, Mask<T::ControlB>) {
|
fn mask<T: Timer8>() -> (RegisterBits<T::ControlA>, RegisterBits<T::ControlB>) {
|
||||||
(!(T::WGM0 | T::WGM1), !(T::WGM2))
|
(!(T::WGM0 | T::WGM1), !(T::WGM2))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Timer8Setup<T: Timer8> {
|
pub struct Timer8Setup<T: Timer8> {
|
||||||
a: Mask<T::ControlA>,
|
a: RegisterBits<T::ControlA>,
|
||||||
b: Mask<T::ControlB>,
|
b: RegisterBits<T::ControlB>,
|
||||||
output_compare_1: Option<u8>,
|
output_compare_1: Option<u8>,
|
||||||
_phantom: marker::PhantomData<T>,
|
_phantom: marker::PhantomData<T>,
|
||||||
}
|
}
|
||||||
|
@ -137,8 +137,8 @@ impl<T: Timer8> Timer8Setup<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Timer8Setup {
|
Timer8Setup {
|
||||||
a: Mask::zero(),
|
a: RegisterBits::zero(),
|
||||||
b: Mask::zero(),
|
b: RegisterBits::zero(),
|
||||||
output_compare_1: None,
|
output_compare_1: None,
|
||||||
_phantom: marker::PhantomData,
|
_phantom: marker::PhantomData,
|
||||||
}
|
}
|
||||||
|
|
15
src/pin.rs
15
src/pin.rs
|
@ -1,7 +1,10 @@
|
||||||
use Register;
|
use Register;
|
||||||
|
|
||||||
|
/// Represents whether a pin is an input or an output.
|
||||||
pub enum DataDirection {
|
pub enum DataDirection {
|
||||||
|
/// The pin is exclusively used for reading signals.
|
||||||
Input,
|
Input,
|
||||||
|
/// The pin is exclusively used for sending signals.
|
||||||
Output,
|
Output,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +14,7 @@ pub trait Pin {
|
||||||
type DDR: Register<T=u8>;
|
type DDR: Register<T=u8>;
|
||||||
/// The associated port register.
|
/// The associated port register.
|
||||||
type PORT: Register<T=u8>;
|
type PORT: Register<T=u8>;
|
||||||
/// The associated pin register.
|
|
||||||
///
|
///
|
||||||
/// Reads from the register will read input bits.
|
/// Reads from the register will read input bits.
|
||||||
/// Writes to the register will toggle bits.
|
/// Writes to the register will toggle bits.
|
||||||
|
@ -31,13 +34,13 @@ pub trait Pin {
|
||||||
/// Sets the pin up as an input.
|
/// Sets the pin up as an input.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn set_input() {
|
fn set_input() {
|
||||||
Self::DDR::unset_raw(Self::MASK);
|
Self::DDR::unset_mask_raw(Self::MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the pin up as an output.
|
/// Sets the pin up as an output.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn set_output() {
|
fn set_output() {
|
||||||
Self::DDR::set_raw(Self::MASK);
|
Self::DDR::set_mask_raw(Self::MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the pin to high.
|
/// Set the pin to high.
|
||||||
|
@ -45,7 +48,7 @@ pub trait Pin {
|
||||||
/// The pin must be configured as an output.
|
/// The pin must be configured as an output.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn set_high() {
|
fn set_high() {
|
||||||
Self::PORT::set_raw(Self::MASK);
|
Self::PORT::set_mask_raw(Self::MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the pin to low.
|
/// Set the pin to low.
|
||||||
|
@ -53,7 +56,7 @@ pub trait Pin {
|
||||||
/// The pin must be configured as an output.
|
/// The pin must be configured as an output.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn set_low() {
|
fn set_low() {
|
||||||
Self::PORT::unset_raw(Self::MASK);
|
Self::PORT::unset_mask_raw(Self::MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Toggles the pin.
|
/// Toggles the pin.
|
||||||
|
@ -72,7 +75,7 @@ pub trait Pin {
|
||||||
/// The pin must be configured as an input.
|
/// The pin must be configured as an input.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn is_high() -> bool {
|
fn is_high() -> bool {
|
||||||
Self::PIN::is_set_raw(Self::MASK)
|
Self::PIN::is_mask_set_raw(Self::MASK)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks if the pin is currently low.
|
/// Checks if the pin is currently low.
|
||||||
|
|
210
src/register.rs
210
src/register.rs
|
@ -1,6 +1,8 @@
|
||||||
use core::{cmp, convert, marker, ops};
|
use core::{cmp, convert, marker, ops};
|
||||||
|
|
||||||
/// A value that a register can store.
|
/// A value that a register can store.
|
||||||
|
///
|
||||||
|
/// All registers are either `u8` or `u16`.
|
||||||
pub trait RegisterValue : Copy + Clone +
|
pub trait RegisterValue : Copy + Clone +
|
||||||
ops::BitAnd<Output=Self> +
|
ops::BitAnd<Output=Self> +
|
||||||
ops::BitAndAssign +
|
ops::BitAndAssign +
|
||||||
|
@ -16,8 +18,11 @@ pub trait RegisterValue : Copy + Clone +
|
||||||
|
|
||||||
/// A register.
|
/// A register.
|
||||||
pub trait Register : Sized {
|
pub trait Register : Sized {
|
||||||
|
/// The type that can represent the value of the register.
|
||||||
type T: RegisterValue;
|
type T: RegisterValue;
|
||||||
type Mask = Mask<Self>;
|
/// The type representing a set of bits that may be manipulated
|
||||||
|
/// within the register.
|
||||||
|
type RegisterBits = RegisterBits<Self>;
|
||||||
|
|
||||||
/// The address of the register.
|
/// The address of the register.
|
||||||
const ADDRESS: *mut Self::T;
|
const ADDRESS: *mut Self::T;
|
||||||
|
@ -36,35 +41,44 @@ pub trait Register : Sized {
|
||||||
unsafe { *Self::ADDRESS }
|
unsafe { *Self::ADDRESS }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set(mask: Mask<Self>) {
|
/// Sets a set of bits to `1` in the register.
|
||||||
Self::set_raw(mask.mask);
|
fn set(bits: RegisterBits<Self>) {
|
||||||
|
Self::set_mask_raw(bits.mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets a bitmask in a register.
|
/// Sets a bitmask in a register.
|
||||||
///
|
///
|
||||||
/// This is equivalent to `r |= mask`.
|
/// This is equivalent to `r |= mask`.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn set_raw(mask: Self::T) {
|
fn set_mask_raw(mask: Self::T) {
|
||||||
unsafe {
|
unsafe {
|
||||||
*Self::ADDRESS |= mask;
|
*Self::ADDRESS |= mask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unset(mask: Mask<Self>) {
|
/// Unsets a set of bits in the register.
|
||||||
Self::unset_raw(mask.mask);
|
///
|
||||||
|
/// All of the bits will be set to `0`.
|
||||||
|
fn unset(bits: RegisterBits<Self>) {
|
||||||
|
Self::unset_mask_raw(bits.mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clears a bitmask from a register.
|
/// Clears a bitmask from a register.
|
||||||
///
|
///
|
||||||
/// This is equivalent to `r &= !mask`.
|
/// This is equivalent to `r &= !mask`.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn unset_raw(mask: Self::T) {
|
fn unset_mask_raw(mask: Self::T) {
|
||||||
unsafe {
|
unsafe {
|
||||||
*Self::ADDRESS &= !mask;
|
*Self::ADDRESS &= !mask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn toggle(mask: Mask<Self>) {
|
/// Toggles a set of bits within the register.
|
||||||
|
///
|
||||||
|
/// All specified bits which were previously `0` will become
|
||||||
|
/// `1`, and all specified bits that were previous `1` will
|
||||||
|
/// become `0`.
|
||||||
|
fn toggle(mask: RegisterBits<Self>) {
|
||||||
Self::toggle_raw(mask.mask);
|
Self::toggle_raw(mask.mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,21 +92,29 @@ pub trait Register : Sized {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_set(mask: Mask<Self>) -> bool {
|
/// Checks if a set of bits are enabled.
|
||||||
Self::is_set_raw(mask.mask)
|
///
|
||||||
|
/// All specifed bits must be set for this function
|
||||||
|
/// to return `true`.
|
||||||
|
fn is_set(bits: RegisterBits<Self>) -> bool {
|
||||||
|
Self::is_mask_set_raw(bits.mask)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks if a mask is set in the register.
|
/// Checks if a mask is set in the register.
|
||||||
///
|
///
|
||||||
/// This is equivalent to `(r & mask) == mask`.
|
/// This is equivalent to `(r & mask) == mask`.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn is_set_raw(mask: Self::T) -> bool {
|
fn is_mask_set_raw(mask: Self::T) -> bool {
|
||||||
unsafe {
|
unsafe {
|
||||||
(*Self::ADDRESS & mask) == mask
|
(*Self::ADDRESS & mask) == mask
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_clear(mask: Mask<Self>) -> bool {
|
/// Checks if a set of bits are not set.
|
||||||
|
///
|
||||||
|
/// All specified bits must be `0` for this
|
||||||
|
/// function to return `true`.
|
||||||
|
fn is_clear(mask: RegisterBits<Self>) -> bool {
|
||||||
Self::is_clear_raw(mask.mask)
|
Self::is_clear_raw(mask.mask)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,6 +128,92 @@ pub trait Register : Sized {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Waits until a set of bits are set in the register.
|
||||||
|
///
|
||||||
|
/// This function will block until all bits that are set in
|
||||||
|
/// the mask are also set in the register.
|
||||||
|
fn wait_until_set(bits: RegisterBits<Self>) {
|
||||||
|
Self::wait_until_mask_set_raw(bits.mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Waits until a bit mask is set in the register.
|
||||||
|
///
|
||||||
|
/// This function will block until all bits that are set in
|
||||||
|
/// the mask are also set in the register.
|
||||||
|
#[inline(always)]
|
||||||
|
fn wait_until_mask_set_raw(mask: Self::T) {
|
||||||
|
wait_until(|| Self::is_mask_set_raw(mask))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents a set of bits within a specific register.
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
pub struct RegisterBits<R: Register> {
|
||||||
|
/// The raw bitmask.
|
||||||
|
mask: R::T,
|
||||||
|
_phantom: marker::PhantomData<R>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<R> RegisterBits<R> where R: Register {
|
||||||
|
/// Creates a new register mask.
|
||||||
|
pub const fn new(mask: R::T) -> Self {
|
||||||
|
RegisterBits { mask, _phantom: marker::PhantomData }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn zero() -> Self {
|
||||||
|
RegisterBits::new(0u8.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<R> ops::BitOr for RegisterBits<R> where R: Register
|
||||||
|
{
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn bitor(self, rhs: Self) -> Self {
|
||||||
|
RegisterBits::new(self.mask | rhs.mask)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<R> ops::BitOrAssign for RegisterBits<R> where R: Register {
|
||||||
|
fn bitor_assign(&mut self, rhs: Self) {
|
||||||
|
self.mask |= rhs.mask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<R> ops::BitAnd for RegisterBits<R> where R: Register
|
||||||
|
{
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn bitand(self, rhs: Self) -> Self {
|
||||||
|
RegisterBits::new(self.mask & rhs.mask)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<R> ops::BitAndAssign for RegisterBits<R> where R: Register {
|
||||||
|
fn bitand_assign(&mut self, rhs: Self) {
|
||||||
|
self.mask &= rhs.mask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<R> ops::Not for RegisterBits<R> where R: Register {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn not(self) -> Self {
|
||||||
|
RegisterBits::new(!self.mask)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<R> Into<u8> for RegisterBits<R> where R: Register<T=u8> {
|
||||||
|
fn into(self) -> u8 { self.mask }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<R> Into<u16> for RegisterBits<R> where R: Register<T=u16> {
|
||||||
|
fn into(self) -> u16 { self.mask }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RegisterValue for u8 { }
|
||||||
|
impl RegisterValue for u16 { }
|
||||||
|
|
||||||
/// Waits until some condition is true of the register.
|
/// Waits until some condition is true of the register.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn wait_until<F>(mut f: F)
|
fn wait_until<F>(mut f: F)
|
||||||
|
@ -117,81 +225,3 @@ pub trait Register : Sized {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wait_until_set(mask: Mask<Self>) {
|
|
||||||
Self::wait_until_set_raw(mask.mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Waits until a mask is set.
|
|
||||||
#[inline(always)]
|
|
||||||
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 Mask<R: Register> {
|
|
||||||
mask: R::T,
|
|
||||||
_phantom: marker::PhantomData<R>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<R> Mask<R> where R: Register {
|
|
||||||
/// Creates a new register mask.
|
|
||||||
pub const fn new(mask: R::T) -> Self {
|
|
||||||
Mask { mask, _phantom: marker::PhantomData }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn zero() -> Self {
|
|
||||||
Mask::new(0u8.into())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<R> ops::BitOr for Mask<R> where R: Register
|
|
||||||
{
|
|
||||||
type Output = Self;
|
|
||||||
|
|
||||||
fn bitor(self, rhs: Self) -> Self {
|
|
||||||
Mask::new(self.mask | rhs.mask)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<R> ops::BitOrAssign for Mask<R> where R: Register {
|
|
||||||
fn bitor_assign(&mut self, rhs: Self) {
|
|
||||||
self.mask |= rhs.mask;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<R> ops::BitAnd for Mask<R> where R: Register
|
|
||||||
{
|
|
||||||
type Output = Self;
|
|
||||||
|
|
||||||
fn bitand(self, rhs: Self) -> Self {
|
|
||||||
Mask::new(self.mask & rhs.mask)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<R> ops::BitAndAssign for Mask<R> where R: Register {
|
|
||||||
fn bitand_assign(&mut self, rhs: Self) {
|
|
||||||
self.mask &= rhs.mask;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<R> ops::Not for Mask<R> where R: Register {
|
|
||||||
type Output = Self;
|
|
||||||
|
|
||||||
fn not(self) -> Self {
|
|
||||||
Mask::new(!self.mask)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<R> Into<u8> for Mask<R> where R: Register<T=u8> {
|
|
||||||
fn into(self) -> u8 { self.mask }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<R> Into<u16> for Mask<R> where R: Register<T=u16> {
|
|
||||||
fn into(self) -> u16 { self.mask }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RegisterValue for u8 { }
|
|
||||||
impl RegisterValue for u16 { }
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue