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
139
140
141
142
143
144
145
146
147
148
use crate::configuration::error::Error;
use num_traits::FromPrimitive;

use super::{
    Configuration, FastFilterThreshold, Hysteresis, OutputStage, PowerMode, PwmFreq,
    SlowFilterMode, WatchdogState,
};

impl TryFrom<u8> for PowerMode {
    type Error = Error;
    fn try_from(byte: u8) -> Result<Self, Self::Error> {
        FromPrimitive::from_u8(byte /* & 0b0000_0011*/).ok_or(Error::PowerModeBitPattern(byte))
    }
}

impl From<PowerMode> for u8 {
    fn from(mode: PowerMode) -> Self {
        mode as Self
    }
}

impl TryFrom<u8> for Hysteresis {
    type Error = Error;
    fn try_from(byte: u8) -> Result<Self, Self::Error> {
        FromPrimitive::from_u8(byte /* & 0b0000_0011*/).ok_or(Error::HysteresisBitPattern(byte))
    }
}

impl From<Hysteresis> for u8 {
    fn from(hyst: Hysteresis) -> Self {
        hyst as Self
    }
}

impl TryFrom<u8> for OutputStage {
    type Error = Error;
    fn try_from(byte: u8) -> Result<Self, Self::Error> {
        match byte & 0b0000_0011 {
            0b00 => Ok(Self::Analog),
            0b01 => Ok(Self::ReducedAnalog),
            0b10 => Ok(Self::DigitalPwm),
            0b11 => Err(Error::OutputStageBitPattern(byte)),
            _ => unreachable!("Bit pattern above eliminates all other bits"),
        }
    }
}

impl From<OutputStage> for u8 {
    fn from(stage: OutputStage) -> Self {
        stage as Self
    }
}

impl TryFrom<u8> for PwmFreq {
    type Error = Error;
    fn try_from(byte: u8) -> Result<Self, Self::Error> {
        FromPrimitive::from_u8(byte /* & 0b0000_0011*/).ok_or(Error::PwmFreqBitPattern(byte))
    }
}

impl From<PwmFreq> for u8 {
    fn from(freq: PwmFreq) -> Self {
        freq as Self
    }
}

impl TryFrom<u8> for SlowFilterMode {
    type Error = Error;
    fn try_from(byte: u8) -> Result<Self, Self::Error> {
        FromPrimitive::from_u8(byte /*& 0b0000_0011*/).ok_or(Error::SlowFilterModeBitPattern(byte))
    }
}

impl From<SlowFilterMode> for u8 {
    fn from(filter: SlowFilterMode) -> Self {
        filter as Self
    }
}

impl TryFrom<u8> for FastFilterThreshold {
    type Error = Error;
    fn try_from(byte: u8) -> Result<Self, Self::Error> {
        FromPrimitive::from_u8(byte /*& 0b0000_0111*/)
            .ok_or(Error::FastFilterThresholdBitPattern(byte))
    }
}

impl From<FastFilterThreshold> for u8 {
    fn from(fth: FastFilterThreshold) -> Self {
        fth as Self
    }
}

impl TryFrom<u8> for WatchdogState {
    type Error = Error;
    fn try_from(byte: u8) -> Result<Self, Self::Error> {
        FromPrimitive::from_u8(byte /*& 0b0000_0001*/).ok_or(Error::WatchdogState(byte))
    }
}

impl From<WatchdogState> for u8 {
    fn from(state: WatchdogState) -> Self {
        state as Self
    }
}

impl TryFrom<u16> for Configuration {
    type Error = Error;
    fn try_from(bytes: u16) -> Result<Self, Self::Error> {
        let pm = (bytes & 0b0000_0000_0000_0011) as u8;
        let hyst = ((bytes & 0b0000_0000_0000_1100) >> 2) as u8;
        let outs = ((bytes & 0b0000_0000_0011_0000) >> 4) as u8;
        let pwmf = ((bytes & 0b0000_0000_1100_0000) >> 6) as u8;
        let sf = ((bytes & 0b0000_0011_0000_0000) >> 8) as u8;
        let fth = ((bytes & 0b0001_1100_0000_0000) >> 10) as u8;
        let wd = ((bytes & 0b0010_0000_0000_0000) >> 13) as u8;
        Ok(Self {
            power_mode: pm.try_into()?,
            hysteresis: hyst.try_into()?,
            output_stage: outs.try_into()?,
            pwm_frequency: pwmf.try_into()?,
            slow_filter: sf.try_into()?,
            fast_filter_threshold: fth.try_into()?,
            watchdog_state: wd.try_into()?,
        })
    }
}

impl From<Configuration> for u16 {
    fn from(config: Configuration) -> Self {
        let mut fields = 0;
        let power_mode_bits = u8::from(config.power_mode) as Self;
        fields |= power_mode_bits;
        let hyst_bits = (u8::from(config.hysteresis) as Self) << 2;
        fields |= hyst_bits;
        let outs_bits = (u8::from(config.output_stage) as Self) << 4;
        fields |= outs_bits;
        let pwmf_bits = (u8::from(config.pwm_frequency) as Self) << 6;
        fields |= pwmf_bits;
        let sf_bits = (u8::from(config.slow_filter) as Self) << 8;
        fields |= sf_bits;
        let fth_bits = (u8::from(config.fast_filter_threshold) as Self) << 10;
        fields |= fth_bits;
        let wd_bits = (u8::from(config.watchdog_state) as Self) << 13;
        fields |= wd_bits;
        fields
    }
}