1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
//! Types and trait needed for this library

use core::convert::TryInto;
use core::fmt::{self, Debug};
use core::marker::PhantomData;
use core::ops::*;

pub use dynreg::*;
pub use field::*;
pub use field_values::*;
pub use fields::*;
pub use reg::*;
pub use value::*;

mod dynreg;
mod field;
mod field_values;
mod fields;
mod reg;
mod value;

use private::*;
mod private {
    use super::*;

    pub trait Int:
        BitAnd<Output = Self>
        + BitOr<Output = Self>
        + BitXor<Output = Self>
        + Not<Output = Self>
        + Shl<usize, Output = Self>
        + Shr<usize, Output = Self>
        + Eq
        + Default
        + fmt::Binary
        + fmt::LowerHex
        + Copy
    {
        const WIDTH: usize;
    }

    impl Int for u8 {
        const WIDTH: usize = 8;
    }
    impl Int for u16 {
        const WIDTH: usize = 16;
    }
    impl Int for u32 {
        const WIDTH: usize = 32;
    }
    impl Int for u64 {
        const WIDTH: usize = 64;
    }
    impl Int for u128 {
        const WIDTH: usize = 128;
    }

    pub trait Both<T> {
        type Output;
    }

    impl<T: MayToggle> Both<()> for T {
        type Output = ();
    }

    impl<T: MayToggle> Both<Toggle> for T {
        type Output = T::Toggle;
    }

    pub trait Either<T> {
        type Output;
    }

    impl<T: MayToggle> Either<()> for T {
        type Output = T::Toggle;
    }

    impl<T: MayToggle> Either<Toggle> for T {
        type Output = Toggle;
    }
}

/// A trait for peripheral instances
///
/// This trait is implemented by the [`device!`] macro for marker types that indicate peripheral instances.
pub trait Peripheral {
    /// The base address of this peripheral instance
    const BASE: usize;
    /// The name to be displayed in debug
    const NAME: &'static str;
}

/// A trait for the register associated with a value
///
/// This trait is implemented by the [`register!`] macro for marker types that indicate registers associated to a value.
pub trait RegisterValue {
    /// The width of this register (`u8`, `u16`, etc.)
    type Int: Int;
    /// The reset value of this register
    const RESET: Self::Int;
    /// The name to be displayed in debug
    const NAME: &'static str;
}

/// A trait for registers
//
/// This trait is implemented by the [`periph!`] macro for marker types that indicate registers.
pub trait Register {
    /// The width of this register (`u8`, `u16`, etc.)
    type Int: Int;
    /// The marker type for values read from this register
    type Value: RegisterValue<Int = Self::Int>;

    /// The offset from the base address
    const OFFSET: usize;
    /// The name to be displayed in debug
    const NAME: &'static str;
}

/// A marker trait for readable registers
pub trait ReadRegister: Register {}

/// A marker trait for writeable register
pub trait WriteRegister: Register {}

/// A marker type for toggleable fields
#[derive(Debug)]
pub enum Toggle {}

/// Whether the fields or fields values may be toggled
pub trait MayToggle {
    /// `Toggle` if it can be toggled, `()` otherwise
    type Toggle;
}

/// Error returned when converting an interger to a field value fails
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct InvalidValue;