1use crate::constant::*;
2use crate::helper::pa_type::{PAReadBias, PASetBias, PATemp, PAError};
3use crate::device::{max11615, max11617, max5825, pca9548a};
4use crate::pb_control::pb_temp::read_pds_temp;
5
6impl PAReadBias {
7 pub fn new() -> Self {
8 match Self::read_bias() {
9 Ok(read_biases) => {
10 read_biases
11 }
12 Err(_) => {
13 Self {
14 read_biases: [f32::MAX; 16]
15 }
16 }
17 }
18 }
19 pub fn read_bias() -> Result<PAReadBias, PAError> {
20 let mut read_biases: [f32; 16] = Default::default();
21
22 let preamp_channels = [
23 PA_SEN_1_CHANNEL, PA_SEN_2_CHANNEL, PA_SEN_3_CHANNEL, PA_SEN_4_CHANNEL,
24 PA_SEN_5_CHANNEL, PA_SEN_6_CHANNEL, PA_SEN_7_CHANNEL, PA_SEN_8_CHANNEL,
25 PA_SEN_9_CHANNEL, PA_SEN_10_CHANNEL, PA_SEN_11_CHANNEL, PA_SEN_12_CHANNEL,
26 PA_SEN_13_CHANNEL, PA_SEN_14_CHANNEL, PA_SEN_15_CHANNEL, PA_SEN_16_CHANNEL,
27 ];
28 let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, PB_PCA9548A_ADDRESS);
29 i2c_mux.select(PB_ADC_1_CHANNEL)?;
30 let max11615 = max11615::MAX11615::new(I2C_BUS, PB_MAX11615_ADDRESS);
31 max11615.setup()?;
32 let max11617 = max11617::MAX11617::new(I2C_BUS, PB_MAX11617_ADDRESS);
33 max11617.setup()?;
34
35 for i in 0..=7 {
36 if (0..=3).contains(&i) {
37 let preamp_bias_raw = max11615.read(preamp_channels[i])?;
38 read_biases[i] = Self::convert_bias_voltage(preamp_bias_raw);
39 } else {
40 let preamp_bias_raw = max11617.read(preamp_channels[i])?;
41 read_biases[i] = Self::convert_bias_voltage(preamp_bias_raw);
42 }
43 }
44
45 i2c_mux.select(PB_ADC_2_CHANNEL)?;
46 max11615.setup()?;
47 max11617.setup()?;
48
49 for i in 8..=15 {
50 if (8..=11).contains(&i) {
51 let preamp_bias_raw = max11615.read(preamp_channels[i])?;
52 read_biases[i] = Self::convert_bias_voltage(preamp_bias_raw);
53 } else {
54 let preamp_bias_raw = max11617.read(preamp_channels[i])?;
55 read_biases[i] = Self::convert_bias_voltage(preamp_bias_raw);
56 }
57 }
58
59 i2c_mux.reset()?;
60
61 Ok(
62 PAReadBias {
63 read_biases,
64 }
65 )
66 }
67 fn convert_bias_voltage(voltage: f32) -> f32 {
68 let bias_voltage = voltage * (10f32.powi(6i32) + 47f32*10f32.powi(3i32))/(47f32*10f32.powi(3i32));
70
71 bias_voltage
72 }
73}
74
75impl PASetBias {
76 pub fn read_set_bias() -> Result<Self, PAError> {
77
78 let preamp_bias_channels = [
79 PA_DAC_1_CHANNEL, PA_DAC_2_CHANNEL, PA_DAC_3_CHANNEL, PA_DAC_4_CHANNEL,
80 PA_DAC_5_CHANNEL, PA_DAC_6_CHANNEL, PA_DAC_7_CHANNEL, PA_DAC_8_CHANNEL,
81 PA_DAC_9_CHANNEL, PA_DAC_10_CHANNEL, PA_DAC_11_CHANNEL, PA_DAC_12_CHANNEL,
82 PA_DAC_13_CHANNEL, PA_DAC_14_CHANNEL, PA_DAC_15_CHANNEL, PA_DAC_16_CHANNEL,
83 ];
84
85 let mut set_biases: [f32; 16] = Default::default();
86
87 let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, PB_PCA9548A_ADDRESS);
88
89 i2c_mux.select(PB_DAC_1_CHANNEL)?;
90 let pb_dac_1 = max5825::MAX5825::new(I2C_BUS, PB_MAX5825_ADDRESS);
91 for i in 0..=7 {
92 set_biases[i] = Self::adc_to_bias(pb_dac_1.read_dacn(preamp_bias_channels[i])?);
93 }
94
95 i2c_mux.select(PB_DAC_2_CHANNEL)?;
96 let pb_dac_2 = max5825::MAX5825::new(I2C_BUS, PB_MAX5825_ADDRESS);
97 for i in 8..=15 {
98 set_biases[i] = Self::adc_to_bias(pb_dac_2.read_dacn(preamp_bias_channels[i])?);
99 }
100
101 i2c_mux.reset()?;
102
103 Ok(
104 Self {
105 set_biases
106 }
107 )
108 }
109 pub fn set_default_bias() -> Result<(), PAError> {
110
111 let bias_voltage = Self::bias_to_adc(PA_DEFAULT_BIAS);
112
113 let preamp_bias_channels = [
114 PA_DAC_1_CHANNEL, PA_DAC_2_CHANNEL, PA_DAC_3_CHANNEL, PA_DAC_4_CHANNEL,
115 PA_DAC_5_CHANNEL, PA_DAC_6_CHANNEL, PA_DAC_7_CHANNEL, PA_DAC_8_CHANNEL,
116 PA_DAC_9_CHANNEL, PA_DAC_10_CHANNEL, PA_DAC_11_CHANNEL, PA_DAC_12_CHANNEL,
117 PA_DAC_13_CHANNEL, PA_DAC_14_CHANNEL, PA_DAC_15_CHANNEL, PA_DAC_16_CHANNEL,
118 ];
119
120 let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, PB_PCA9548A_ADDRESS);
121
122 i2c_mux.select(PB_DAC_1_CHANNEL)?;
123 let pb_dac_1 = max5825::MAX5825::new(I2C_BUS, PB_MAX5825_ADDRESS);
124 for i in 0..=7 {
125 pb_dac_1.coden_loadn(preamp_bias_channels[i], bias_voltage)?;
126 }
127
128 i2c_mux.select(PB_DAC_2_CHANNEL)?;
129 let pb_dac_2 = max5825::MAX5825::new(I2C_BUS, PB_MAX5825_ADDRESS);
130 for i in 8..=15 {
131 pb_dac_2.coden_loadn(preamp_bias_channels[i], bias_voltage)?;
132 }
133
134 i2c_mux.reset()?;
135
136 Ok(())
137
138 }
139 pub fn set_manual_bias(channel: Option<u8>, bias: f32) -> Result<(), PAError> {
140
141 if bias < 0.0 || bias > 67.0 {
142 eprintln!("Bias voltage must be between 0V to 67V");
143 std::process::exit(1);
144 }
145
146 let bias_voltage = Self::bias_to_adc(bias);
147
148 let preamp_bias_channels = [
149 PA_DAC_1_CHANNEL, PA_DAC_2_CHANNEL, PA_DAC_3_CHANNEL, PA_DAC_4_CHANNEL,
150 PA_DAC_5_CHANNEL, PA_DAC_6_CHANNEL, PA_DAC_7_CHANNEL, PA_DAC_8_CHANNEL,
151 PA_DAC_9_CHANNEL, PA_DAC_10_CHANNEL, PA_DAC_11_CHANNEL, PA_DAC_12_CHANNEL,
152 PA_DAC_13_CHANNEL, PA_DAC_14_CHANNEL, PA_DAC_15_CHANNEL, PA_DAC_16_CHANNEL,
153 ];
154
155 let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, PB_PCA9548A_ADDRESS);
156 match channel {
157 None => {
158 i2c_mux.select(PB_DAC_1_CHANNEL)?;
159 let pb_dac_1 = max5825::MAX5825::new(I2C_BUS, PB_MAX5825_ADDRESS);
160 for i in 0..=7 {
161 pb_dac_1.coden_loadn(preamp_bias_channels[i], bias_voltage)?;
162 }
163
164 i2c_mux.select(PB_DAC_2_CHANNEL)?;
165 let pb_dac_2 = max5825::MAX5825::new(I2C_BUS, PB_MAX5825_ADDRESS);
166 for i in 8..=15 {
167 pb_dac_2.coden_loadn(preamp_bias_channels[i], bias_voltage)?;
168 }
169 }
170 Some(mut ch) => {
171
172 if ch < 1 || ch > 16 {
173 eprintln!("Channel must be between 1 to 16.");
174 std::process::exit(1);
175 }
176
177 ch = ch - 1;
178
179 if (0..=7).contains(&ch) {
180 i2c_mux.select(PB_DAC_1_CHANNEL)?;
181 let pb_dac_1 = max5825::MAX5825::new(I2C_BUS, PB_MAX5825_ADDRESS);
182 pb_dac_1.coden_loadn(preamp_bias_channels[ch as usize], bias_voltage)?;
183 } else {
184 i2c_mux.select(PB_DAC_2_CHANNEL)?;
185 let pb_dac_2 = max5825::MAX5825::new(I2C_BUS, PB_MAX5825_ADDRESS);
186 pb_dac_2.coden_loadn(preamp_bias_channels[ch as usize], bias_voltage)?
187 }
188 }
189 }
190
191 i2c_mux.reset()?;
192
193 Ok(())
194 }
195 pub fn set_manual_biases(biases: [f32; 16]) -> Result<(), PAError> {
196
197 for bias in biases {
198 if bias < 0.0 || bias > 67.0 {
199 eprintln!("Bias voltage must be between 0V to 67V");
200 std::process::exit(1);
201 }
202 }
203
204 let preamp_bias_channels = [
205 PA_DAC_1_CHANNEL, PA_DAC_2_CHANNEL, PA_DAC_3_CHANNEL, PA_DAC_4_CHANNEL,
206 PA_DAC_5_CHANNEL, PA_DAC_6_CHANNEL, PA_DAC_7_CHANNEL, PA_DAC_8_CHANNEL,
207 PA_DAC_9_CHANNEL, PA_DAC_10_CHANNEL, PA_DAC_11_CHANNEL, PA_DAC_12_CHANNEL,
208 PA_DAC_13_CHANNEL, PA_DAC_14_CHANNEL, PA_DAC_15_CHANNEL, PA_DAC_16_CHANNEL,
209 ];
210
211 let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, PB_PCA9548A_ADDRESS);
212
213 i2c_mux.select(PB_DAC_1_CHANNEL)?;
214 let pb_dac_1 = max5825::MAX5825::new(I2C_BUS, PB_MAX5825_ADDRESS);
215 for i in 0..=7 {
216 pb_dac_1.coden_loadn(preamp_bias_channels[i], Self::bias_to_adc(biases[i]))?;
217 }
218
219 i2c_mux.select(PB_DAC_2_CHANNEL)?;
220 let pb_dac_2 = max5825::MAX5825::new(I2C_BUS, PB_MAX5825_ADDRESS);
221 for i in 8..=15 {
222 pb_dac_2.coden_loadn(preamp_bias_channels[i], Self::bias_to_adc(biases[i]))?;
223 }
224
225 i2c_mux.reset()?;
226
227 Ok(())
228 }
229 pub fn set_bias() -> Result<(), PAError> {
230
231 let preamp_bias_channels = [
234 PA_DAC_1_CHANNEL, PA_DAC_2_CHANNEL, PA_DAC_3_CHANNEL, PA_DAC_4_CHANNEL,
235 PA_DAC_5_CHANNEL, PA_DAC_6_CHANNEL, PA_DAC_7_CHANNEL, PA_DAC_8_CHANNEL,
236 PA_DAC_9_CHANNEL, PA_DAC_10_CHANNEL, PA_DAC_11_CHANNEL, PA_DAC_12_CHANNEL,
237 PA_DAC_13_CHANNEL, PA_DAC_14_CHANNEL, PA_DAC_15_CHANNEL, PA_DAC_16_CHANNEL,
238 ];
239
240 let mut bias_voltages: [u16; 16] = Default::default();
241
242 let read_biases = PAReadBias::read_bias()?.read_biases;
243 let set_biases = Self::read_set_bias()?.set_biases;
244
245 for i in 0..=15 {
246 if set_biases[i] == 0.0 {
247 let bias_stc = Self::sipm_temp_comp(i)?;
248 let bias_ptc = Self::pb_temp_comp(bias_stc)?;
249
250 bias_voltages[i] = Self::bias_to_adc(bias_ptc);
251 } else {
255 let delta = (read_biases[i] - set_biases[i]).abs();
256 if delta > 0.1 {
257 if read_biases[i] > set_biases[i] {
258 bias_voltages[i] = Self::bias_to_adc(set_biases[i] + delta);
259 } else if read_biases[i] < set_biases[i] {
263 bias_voltages[i] = Self::bias_to_adc(set_biases[i] - delta);
264 } else {
268 bias_voltages[i] = Self::bias_to_adc(set_biases[i]);
269 }
273 } else {
274 let bias_stc = Self::sipm_temp_comp(i)?;
275 let bias_ptc = Self::pb_temp_comp(bias_stc)?;
276
277 bias_voltages[i] = Self::bias_to_adc(bias_ptc);
278 }
282 }
283 }
284
285 let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, PB_PCA9548A_ADDRESS);
286
287 i2c_mux.select(PB_DAC_1_CHANNEL)?;
288 let pb_dac_1 = max5825::MAX5825::new(I2C_BUS, PB_MAX5825_ADDRESS);
289 for i in 0..=7 {
290 pb_dac_1.coden_loadn(preamp_bias_channels[i], bias_voltages[i])?;
291 }
292
293 i2c_mux.select(PB_DAC_2_CHANNEL)?;
294 let pb_dac_2 = max5825::MAX5825::new(I2C_BUS, PB_MAX5825_ADDRESS);
295 for i in 8..=15 {
296 pb_dac_2.coden_loadn(preamp_bias_channels[i], bias_voltages[i])?;
297 }
298
299 i2c_mux.reset()?;
300
301 Ok(())
302 }
303 pub fn sipm_temp_comp(ch: usize) -> Result<f32, PAError> {
304 let bias_voltage;
305
306 let preamp_temp = PATemp::read_signle_temp(ch)?;
307 if preamp_temp == f32::MAX {
308 bias_voltage = 0.0
309 } else {
310 if (0..=15).contains(&ch) {
311 bias_voltage = PA_DEFAULT_BIAS + (preamp_temp - 20.0) * 0.054;
312 } else {
313 bias_voltage = 0.0;
314 }
315 }
316 Ok(bias_voltage)
323 }
324 pub fn pb_temp_comp(bias_stc: f32) -> Result<f32, PAError> {
325 let pb_temp = read_pds_temp()?;
326
327 let bias_voltage = bias_stc - 0.2 + 0.005 * pb_temp + 4.0 * 10f32.powi(-5) * pb_temp.powi(2);
328
329 Ok(bias_voltage)
330 }
331 pub fn reset_bias() -> Result<(), PAError> {
332 let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, PB_PCA9548A_ADDRESS);
333
334 i2c_mux.select(PB_DAC_1_CHANNEL)?;
335 let pb_dac = max5825::MAX5825::new(I2C_BUS, PB_MAX5825_ADDRESS);
336 pb_dac.reset_dac()?;
337 i2c_mux.select(PB_DAC_2_CHANNEL)?;
338 pb_dac.reset_dac()?;
339
340 i2c_mux.reset()?;
341
342 Ok(())
343
344 }
345 fn bias_to_adc(bias_voltage: f32) -> u16 {
346 let adc = (bias_voltage / 22.3) / PB_DAC_REF_VOLTAGE * 2f32.powi(12);
347
348 adc as u16
349 }
350 fn adc_to_bias(adc: u16) -> f32 {
351 let bias_voltage = adc as f32 * PB_DAC_REF_VOLTAGE * 22.3 * 2f32.powi(-12);
352
353 bias_voltage
354 }
355
356}