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
use super::clock::ClockMask;

#[derive(Copy, Clone)]
pub enum BitOrder {
    /// The least significant bit is sent first.
    LeastSignificantBit,
    /// The most significant bit is sent first.
    MostSignificantBit,
}

#[derive(Copy, Clone)]
pub enum ClockPhase {
    LeadingEdge,
    TrailingEdge,
}

/// SPI settings.
#[derive(Copy, Clone)]
pub struct Settings {
    /// Whether the SPI module is enabled.
    enabled: bool,
    /// Whether to be configured as a master or slave.
    master: bool,
    /// The clock speed.
    clock: u32,
    /// The bit ordering.
    bit_order: BitOrder,
    /// The clock phase.
    clock_phase: ClockPhase,
    /// Whether interrupts should be enabled.
    enable_interrupts: bool,
}

impl Settings {
    /// Gets the default settings for the master.
    pub fn master() -> Self {
        Settings {
            master: true,
            ..Default::default()
        }
    }

    /// Gets the default settings for the slave.
    pub fn slave() -> Self {
        Settings {
            master: false,
            ..Default::default()
        }
    }

    pub fn control_register_bits(self) -> u8 {
        let mut bits = 0;

        bits |= self.clock().control_register_mask();

        if self.enable_interrupts {
            bits |= control_register::INTERRUPT_ENABLE
        }
        if self.enabled {
            bits |= control_register::ENABLE
        }
        if let ClockPhase::LeadingEdge = self.clock_phase {
            bits |= control_register::CPHA;
        }

        if let BitOrder::LeastSignificantBit = self.bit_order {
            bits |= control_register::DATA_ORDER_LSB;
        }
        bits
    }

    pub fn status_register_bits(self) -> u8 {
        let mut bits = 0;

        bits |= self.clock().status_register_mask();
        bits
    }

    fn clock(self) -> ClockMask {
        ClockMask::with_clock(self.clock)
    }
}

impl Default for Settings {
    fn default() -> Settings {
        Settings {
            enabled: true,
            master: true,
            // same as Arduino default in `SPI.h`.
            clock: 4_000_000,
            bit_order: BitOrder::MostSignificantBit,
            clock_phase: ClockPhase::LeadingEdge,
            enable_interrupts: false,
        }
    }
}

/// Constants for the control register.
#[allow(dead_code)]
pub mod control_register {
    /// Set if interrupts are enabled.
    pub const INTERRUPT_ENABLE: u8 = 1 << 7;
    /// Set if the SPI module is enabled.
    pub const ENABLE: u8 = 1 << 6;
    /// Set if data is sent in LSB format.
    pub const DATA_ORDER_LSB: u8 = 1 << 5;
    /// Set if we are configuring a master.
    pub const MASTER: u8 = 1 << 4;
    /// Clock polarity.
    pub const CPOL: u8 = 1 << 3;
    /// Clock phase.
    pub const CPHA: u8 = 1 << 2;
    /// Clock rate select 1.
    pub const SPR1: u8 = 1 << 1;
    /// Clock rate select 2.
    pub const SPR0: u8 = 1 << 0;
}

/// Constants for the status register.
#[allow(dead_code)]
pub mod status_register {
    /// SPI interrupt flag.
    pub const SPIF: u8 = 1 << 7;
    /// Write collision flag.
    pub const WCOL: u8 = 1 << 6;
    /// SPI double speed mode.
    pub const SPI2X: u8 = 1 << 0;
}