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
//! All the traits and typestates related to pins.

/// Implemented by types that identify pins
pub trait PinId {
    /// This is `X` for `PIOX_Y`.
    const PORT: usize;

    /// This is `Y` for `PIOX_Y`.
    const NUMBER: u8;

    /// This is `0x00000001` for [`PIO0_0`], `0x00000002` for [`PIO0_1`],
    /// `0x00000004` for [`PIO0_2`], and so forth.
    const MASK: u32;

    /// This is `0x00000001` for [`PIO0_0`], `0x00000002` for [`PIO0_1`],
    /// This is `0x00000041` for [`PIO1_0`], `0x00000012` for [`PIO1_1`],
    /// etc.
    const OFFSET: usize;

    const TYPE: PinType;
}

pub enum PinType {
    /// Digital only
    D, // igitalOnly,
    /// Analog or digital
    A, // nalogOrDigital,
    /// I2C or digital
    I, // 2C,
}

/// Contains types that indicate pin states
pub mod state {
    use super::gpio::direction::Direction;
    use super::function::Function;
    use crate::typestates::reg_proxy::RegClusterProxy;

    /// Implemented by types that indicate pin state
    pub trait PinState {}

    /// Marks a [`Pin`] as being unused
    pub struct Unused;
    impl PinState for Unused {}

    /// Marks a [`Pin`]  as being assigned to general-purpose I/O
    ///
    /// TODO: It would be much nicer to use B or W instead of PIN,
    /// as then each pin could have just its own register to read
    /// and write to. This needs some work on the SVD.
    pub struct Gpio<D: Direction> {
        // pub(crate) b: RegClusterProxy<raw::gpio::B>,
        // pub(crate) w: RegClusterProxy<raw::gpio::W>,
        pub(crate) dirset: RegClusterProxy<raw::gpio::DIRSET>,
        pub(crate) dirclr: RegClusterProxy<raw::gpio::DIRCLR>,
        pub(crate) pin: RegClusterProxy<raw::gpio::PIN>,
        pub(crate) set: RegClusterProxy<raw::gpio::SET>,
        pub(crate) clr: RegClusterProxy<raw::gpio::CLR>,

        pub(crate) _direction: D,
    }

    pub struct Analog<D: Direction> {
        pub channel: u8,
        pub(crate) dirclr: RegClusterProxy<raw::gpio::DIRCLR>,
        pub(crate) _direction: D,
    }


    impl<D> PinState for Gpio<D> where D: Direction {}
    impl<D> PinState for Analog<D> where D: Direction {}

    pub struct Special<F: Function> {
        pub(crate) _function: F,
    }

    impl<F> PinState for Special<F> where F: Function {}
}

pub mod gpio {
    pub mod direction {
        /// Implemented by types that indicate GPIO pin direction
        pub trait Direction {}

        pub struct Unknown;
        impl Direction for Unknown {}

        pub struct Input;
        impl Direction for Input {}

        pub struct Output;
        impl Direction for Output {}

        pub struct AnalogInput;
        impl Direction for AnalogInput{}

        pub struct AnalogOutput;
        impl Direction for AnalogOutput {}

        pub trait NotInput: Direction {}
        impl NotInput for Unknown {}
        impl NotInput for Output {}

        pub trait NotOutput: Direction {}
        impl NotOutput for Unknown {}
        impl NotOutput for Input {}
    }

    pub enum Level {
        Low,
        High,
    }
}

pub mod function;

pub mod flexcomm;