1#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
2pub struct StageConfiguration(pub(crate) InternalStageConfiguration);
3
4impl StageConfiguration {
5 pub fn builder() -> StageConfigurationBuilder {
6 StageConfigurationBuilder {
7 configuration: InternalStageConfiguration::default(),
8 input_connections: heapless::Vec::new(),
9 }
10 }
11}
12
13pub struct StageConfigurationBuilder {
14 configuration: InternalStageConfiguration,
15 input_connections: heapless::Vec<InputConnection, 12>,
16}
17
18impl StageConfigurationBuilder {
19 pub fn calibration_enabled(mut self, enabled: bool) -> StageConfigurationBuilder {
20 self.configuration.global.calibration_enabled = enabled;
21 self
22 }
23
24 pub fn low_interrupt_enabled(mut self, enabled: bool) -> StageConfigurationBuilder {
25 self.configuration.global.low_int_enabled = enabled;
26 self
27 }
28
29 pub fn high_interrupt_enabled(mut self, enabled: bool) -> StageConfigurationBuilder {
30 self.configuration.global.high_int_enabled = enabled;
31 self
32 }
33
34 pub fn conversion_complete_interrupt_enabled(
35 mut self,
36 enabled: bool,
37 ) -> StageConfigurationBuilder {
38 self.configuration.global.complete_int_enabled = enabled;
39 self
40 }
41
42 pub fn add_input_connection(
43 mut self,
44 input_connection: InputConnection,
45 ) -> StageConfigurationBuilder {
46 let _ = self.input_connections.push(input_connection);
47 self
48 }
49
50 pub fn sensitivity(mut self, sensitivity: StageSensitivity) -> StageConfigurationBuilder {
51 self.configuration.sensitivity = sensitivity;
52 self
53 }
54
55 pub fn initial_offset_low(mut self, offset: u16) -> StageConfigurationBuilder {
56 self.configuration.initial_offset_low = offset;
57 self
58 }
59
60 pub fn initial_offset_high(mut self, offset: u16) -> StageConfigurationBuilder {
61 self.configuration.initial_offset_high = offset;
62 self
63 }
64
65 pub fn offset_high_clamp(mut self, clamp: u16) -> StageConfigurationBuilder {
66 self.configuration.offset_high_clamp = clamp;
67 self
68 }
69
70 pub fn offset_low_clamp(mut self, clamp: u16) -> StageConfigurationBuilder {
71 self.configuration.offset_low_clamp = clamp;
72 self
73 }
74
75 pub fn pos_afe_offset(mut self, offset: u8) -> StageConfigurationBuilder {
76 self.configuration.afe_offset_configuration.pos_afe_offset = offset;
77 self
78 }
79
80 pub fn neg_afe_offset(mut self, offset: u8) -> StageConfigurationBuilder {
81 self.configuration.afe_offset_configuration.neg_afe_offset = offset;
82 self
83 }
84
85 pub fn build(mut self) -> StageConfiguration {
86 if self.input_connections.len() > 1 {
87 self.configuration.input_configuration =
88 InputMode::Differential([self.input_connections[0], self.input_connections[1]]);
89 } else {
90 self.configuration.input_configuration =
91 InputMode::SingleEnded(self.input_connections[0]);
92 }
93 StageConfiguration(self.configuration)
94 }
95}
96
97#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
98pub(crate) struct InternalStageConfiguration {
99 input_configuration: InputMode,
100 neg_afe_offset_disable: bool,
101 pos_afe_offset_disable: bool,
102 afe_offset_configuration: AfeOffsetConfiguration,
103 sensitivity: StageSensitivity,
104 initial_offset_low: u16,
105 initial_offset_high: u16,
106 offset_high_clamp: u16,
107 offset_low_clamp: u16,
108 pub(crate) global: StageGlobalConfig,
109}
110
111impl InternalStageConfiguration {
112 pub(crate) fn to_reg_value(self) -> [u16; 8] {
113 let mut res = [0u16; 8];
114 res[0..2].copy_from_slice(&self.input_configuration.to_reg_value());
115 res[1] |= (self.neg_afe_offset_disable as u16) << 14;
116 res[1] |= (self.pos_afe_offset_disable as u16) << 15;
117 res[2] = self.afe_offset_configuration.to_reg_value();
118 res[3] = self.sensitivity.to_reg_value();
119 res[4] = self.initial_offset_low;
120 res[5] = self.initial_offset_high;
121 res[6] = self.offset_high_clamp;
122 res[7] = self.offset_low_clamp;
123 res
124 }
125}
126
127#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
128pub(crate) struct StageGlobalConfig {
129 pub(crate) calibration_enabled: bool,
130 pub(crate) low_int_enabled: bool,
131 pub(crate) high_int_enabled: bool,
132 pub(crate) complete_int_enabled: bool,
133}
134
135#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
136enum InputMode {
137 #[default]
138 NotConfigured,
139 SingleEnded(InputConnection),
140 Differential([InputConnection; 2]),
141}
142
143impl InputMode {
144 pub(crate) fn to_reg_value(self) -> [u16; 2] {
145 let mut res = 0u32;
146 match self {
147 Self::NotConfigured => {
148 panic!("Input mode cannot be left unconfigured")
149 }
150 InputMode::SingleEnded(conn) => {
151 res |= 0xFFFFFFFF >> 4;
152 res &= ((conn.cdc as u32) << (conn.cin as u32)) | !(0b11 << (conn.cin as u32));
153 res |= if conn.cdc == CdcInput::Positive {
154 0b01
155 } else {
156 0b10
157 } << 28;
158 }
159 InputMode::Differential(conns) => {
160 res |= 0xFFFFFFFF >> 4;
161 for conn in conns {
162 res &= ((conn.cdc as u32) << (conn.cin as u32)) | !(0b11 << (conn.cin as u32));
163 }
164 res |= 0b11 << 28;
165 }
166 }
167 [res as u16, (res >> 16) as u16]
168 }
169}
170
171#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
172pub struct InputConnection {
173 pub cin: CapInput,
174 pub cdc: CdcInput,
175}
176
177#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
178pub enum CapInput {
179 CIN0 = 0,
180 CIN1 = 2,
181 CIN2 = 4,
182 CIN3 = 6,
183 CIN4 = 8,
184 CIN5 = 10,
185 CIN6 = 12,
186 CIN7 = 16,
187 CIN8 = 18,
188 CIN9 = 20,
189 CIN10 = 22,
190 CIN11 = 24,
191 CIN12 = 26,
192}
193
194#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
195pub enum CdcInput {
196 Positive = 0b10,
197 Negative = 0b01,
198}
199
200#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
201struct AfeOffsetConfiguration {
202 neg_afe_offset: u8,
203 neg_afe_offset_swap: bool,
204 pos_afe_offset: u8,
205 pos_afe_offset_swap: bool,
206}
207
208impl AfeOffsetConfiguration {
209 pub(crate) fn to_reg_value(self) -> u16 {
210 let mut res = 0u16;
211 res |= (self.neg_afe_offset & 0b00011111) as u16;
212 res |= (self.neg_afe_offset_swap as u16) << 7;
213 res |= ((self.pos_afe_offset & 0b00011111) as u16) << 8;
214 res |= (self.pos_afe_offset_swap as u16) << 15;
215 res
216 }
217}
218
219#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
220pub struct StageSensitivity {
221 pub neg_threshold_sensitivity: ThresholdSensitivity,
222 pub neg_peak_detect: PeakDetect,
223 pub pos_threshold_sensitivity: ThresholdSensitivity,
224 pub pos_peak_detect: PeakDetect,
225}
226
227impl StageSensitivity {
228 pub(crate) fn to_reg_value(self) -> u16 {
229 let mut res = 0u16;
230 res |= self.neg_threshold_sensitivity as u16;
231 res |= (self.neg_peak_detect as u16) << 4;
232 res |= (self.pos_threshold_sensitivity as u16) << 8;
233 res |= (self.pos_peak_detect as u16) << 12;
234 res
235 }
236}
237
238#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
239pub enum ThresholdSensitivity {
240 #[default]
241 Percent25 = 0,
242 Percent29 = 1,
243 Percent34 = 2,
244 Percent39 = 3,
245 Percent43 = 4,
246 Percent48 = 5,
247 Percent53 = 6,
248 Percent58 = 7,
249 Percent62 = 8,
250 Percent67 = 9,
251 Percent71 = 10,
252 Percent76 = 11,
253 Percent81 = 12,
254 Percent85 = 13,
255 Percent90 = 14,
256 Percent95 = 15,
257}
258
259#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
260pub enum PeakDetect {
261 #[default]
262 Percent40 = 0,
263 Percent50 = 1,
264 Percent60 = 2,
265 Percent70 = 3,
266 Percent80 = 4,
267 Percent90 = 5,
268}