1#![no_std]
2#![allow(dead_code)]
3#![allow(unused_variables)]
4
5pub mod error;
7
8
9use crate::data::{Bmp3Configuration, ControlFrameEnum, FifoConfig1, FifoConfig2, SensorFrameEnum, TandPtype};
10use crate::error::Error;
11
12pub mod data;
13pub mod constants;
16
17use crate::constants::DeviceAddress::{Primary, Secondary};
18
19
20
21use constants::{BMP3_REG_CHIP_ID, BMP3_REG_ERR, BMP3_REG_SENS_STATUS, BMP3_REG_PRESS_DATA, BMP3_REG_TEMP_DATA,
22 BMP3_REG_SENSOR_TIME, BMP3_REG_EVENT, BMP3_REG_INT_STATUS, BMP3_REG_FIFO_LENGTH, BMP3_REG_FIFO_DATA,
23 BMP3_REG_FIFO_WM, BMP3_REG_FIFO_CONFIG_1, BMP3_REG_FIFO_CONFIG_2, BMP3_REG_INT_CTRL,
24 BMP3_REG_IF_CONF, BMP3_REG_PWR_CTRL, BMP3_REG_OSR, BMP3_REG_ODR, BMP3_REG_CONFIG, BMP3_REG_CALIB_DATA,
25 BMP3_REG_CMD, BMP3_SOFT_RESET, BMP3_FIFO_FLUSH};
26
27use data::{DeviceInfo, DeviceModel, Measurements, PWR_CTRL, PowerMode, Status, ErrorReg, IntStatus, Odr, Over_Sampling,
28 OSR, FilterCoef, CalibrationPars, InterruptPinControl, Fifo_Config, FifoFrame};
29
30#[cfg(not(feature = "async"))]
31use embedded_hal::{i2c::I2c, delay::DelayNs};
32#[cfg(feature = "async")]
33use embedded_hal_async::{i2c::I2c as AsyncI2c, delay::DelayNs as AsyncDelayNs};
34
35use log::{debug, info};
36use libm::{pow, truncf};
37
38const STANDARD_SEA_LEVEL_AIR_PRESSURE: f64 = 101325.0; pub struct BMP38x<I2C, D> {
43 i2c: I2C,
45 address: u8,
47 delayer: D,
48 pub device_info: DeviceInfo,
49 cal_pars: CalibrationPars,
50 fifo_config: Fifo_Config,
51 pub altitude_m: f64,
53}
54
55#[cfg(not(feature = "async"))]
56impl<I2C, D, E> BMP38x<I2C, D>
57where
58 I2C: I2c<Error = E>,
59 D: DelayNs,
60{
61
62 pub fn new(i2c: I2C, address: u8, delayer: D) -> Self {
65 log::debug!("new called");
66 Self {
67 i2c,
68 address: address,
69 delayer,
70 device_info: DeviceInfo { ..Default::default()},
71 cal_pars: CalibrationPars { .. Default::default()},
72 fifo_config: Fifo_Config { .. Default::default()},
73 altitude_m : 0.0,
74 }
75 }
76
77 pub fn new_with_altitude(i2c: I2C, address: u8, delayer: D, altitude: f64) -> Self {
78 log::debug!("new_with_altitude called");
79 Self {
80 i2c,
81 address: address,
82 delayer,
83 device_info: DeviceInfo { ..Default::default()},
84 cal_pars: CalibrationPars { .. Default::default()},
85 fifo_config: Fifo_Config { ..Default::default()},
86 altitude_m : altitude,
87 }
88 }
89
90 pub fn release(self) -> I2C {
92 self.i2c
93 }
94
95}
96
97#[cfg(feature = "async")]
98impl<I2C, D, E> BMP38x<I2C, D>
99where
100 I2C: AsyncI2c<Error = E>,
101 D: AsyncDelayNs,
102{
103 pub fn new(i2c: I2C, address: u8, delayer: D) -> Self {
106 debug!("new called");
107 Self {
108 i2c,
109 address: address,
110 delayer,
111 device_info: DeviceInfo { ..Default::default()},
112 cal_pars: CalibrationPars::default(),
113 }
114 }
115
116 pub fn release(self) -> I2C {
118 self.i2c
119 }
120
121}
122
123#[maybe_async_cfg::maybe(
124 sync(
125 cfg(not(feature = "async")),
126 self = "BMP38x",
127 idents(AsyncI2c(sync = "I2c"), AsyncDelayNs(sync = "DelayNs"))
128 ),
129 async(feature = "async", keep_self)
130)]
131
132impl<I2C, D, E> BMP38x<I2C, D>
133where
134 I2C: AsyncI2c<Error = E>,
135 D: AsyncDelayNs,
136{
137
138 async fn write_command<const N: usize>(&mut self, command_buf: [u8; N] ) -> Result<(), Error<E>> {
140 self.i2c
142 .write(self.address, &command_buf).await
143 .map_err(Error::I2c)?;
144 Ok(())
145 }
146
147 async fn read_register( &mut self, register_address: u8, buffer: &mut [u8] ) -> Result<(), Error<E>> {
148 let mut command_buffer = [0u8; 1];
149 command_buffer[0] = register_address;
150 self.i2c
152 .write_read(self.address, &command_buffer, buffer).await
153 .map_err(Error::I2c)?;
154 Ok(())
155 }
156
157
158
159
160 pub async fn reset_device(&mut self) -> Result<(), Error<E>> {
162 debug!("in reset_device()");
163 let mut result_buf: [u8; 1] = [0; 1];
165 self.read_register(BMP3_REG_SENS_STATUS, &mut result_buf).await?;
166 let status = Status(result_buf[0]);
167 if (status.get_cmd_ready()) {
168 self.write_command([BMP3_REG_CMD, BMP3_SOFT_RESET]).await?;
170
171 self.delayer.delay_ms(5).await;
176 self.read_register(BMP3_REG_EVENT, &mut result_buf).await?; self.read_register(BMP3_REG_ERR, &mut result_buf).await?;
178 let error_value = ErrorReg(result_buf[0]);
179 if ( error_value.get_cfg_error() || error_value.get_cmd_error() || error_value.get_fatal_error() ) {
180 return Err(Error::CommandError);
181 }
182 return Ok(());
183 }
184 Err(Error::NotReadyForCommand)
185 }
186
187
188 pub async fn init_device(&mut self) -> Result<bool, Error<E>> {
191 debug!("in init_device(), doing reset_device");
194 self.reset_device().await?;
195 if (self.get_chip_id().await? == DeviceModel::NotRead) {
198 debug!("device model is not read");
199 return Ok(false);
200 }
201 debug!("reading calibration pars");
202 self.read_calibration_pars()?;
203 self.set_power_control_mode(PowerMode::Normal)?;
204 let pwr_ctrl_now = self.get_power_mode().await?;
205 debug!(" power_control_mode is now {:?}", pwr_ctrl_now);
206 self.set_pressure_enable(true)?;
207 self.set_temperature_enable(true)?;
208 let pwr_ctrl_now = self.get_power_mode().await?;
209 debug!(" power_control_mode is after press and temp enabled {:?}", pwr_ctrl_now);
210 Ok(true)
211 }
212
213
214 pub async fn get_chip_id(&mut self) -> Result<DeviceModel, Error<E>> {
216 let mut result_buf: [u8; 1] = [0; 1];
217 let mut command_buffer: [u8; 1] = [BMP3_REG_CHIP_ID];
218 self.i2c
219 .write_read(self.address, &command_buffer, &mut result_buf).await
220 .map_err(Error::I2c)?;
221 self.device_info.id = DeviceModel::from(result_buf[0]);
222
223 Ok(DeviceModel::from(result_buf[0]))
224 }
225
226 pub async fn get_status(&mut self) -> Result<Status, Error<E>> {
228 debug!("in get_status()");
229 let mut result_buf: [u8; 1] = [0; 1];
231 self.read_register(BMP3_REG_SENS_STATUS, &mut result_buf).await?;
232 let status = Status(result_buf[0]);
234 Ok(status)
235 }
236
237 pub async fn set_power_mode(&mut self, power_mode: PowerMode) -> Result<(), Error<E>> {
239 debug!("in set_power_mode( {:?} )", power_mode);
240 let mut result_buf: [u8; 1] = [0; 1];
241 self.read_register(BMP3_REG_PWR_CTRL, &mut result_buf).await?;
242 let mut pwr_ctrl: PWR_CTRL = PWR_CTRL(result_buf[0]);
243 pwr_ctrl.set_power_mode(power_mode as u8);
244 self.write_command([BMP3_REG_PWR_CTRL, pwr_ctrl.0]).await?;
245 self.delayer.delay_ms(20).await;
246 Ok(())
247 }
248
249 pub async fn set_pressure_enable(&mut self, enable: bool) -> Result<(), Error<E>> {
251 debug!("in set_pressure_enable()");
252 let mut result_buf: [u8; 1] = [0; 1];
253 self.read_register(BMP3_REG_PWR_CTRL, & mut result_buf).await?;
254 debug!(" read BMP3_REG_PWR_CTRL = {:b}", result_buf[0]);
255 let mut pwr_ctrl: PWR_CTRL = PWR_CTRL(result_buf[0]);
256 pwr_ctrl.set_press_en(enable);
257 debug!(" writing pwr_ctrl {:#b}", pwr_ctrl.0);
258 self.write_command([BMP3_REG_PWR_CTRL, pwr_ctrl.0]).await?;
259 self.delayer.delay_ms(20).await;
260 Ok(())
261 }
262
263 pub async fn set_temperature_enable(&mut self, enable: bool) -> Result<(), Error<E>> {
265 debug!("in set_temperature_enable()");
266 let mut result_buf: [u8; 1] = [0; 1];
267 self.read_register(BMP3_REG_PWR_CTRL, &mut result_buf).await?;
268 debug!(" read BMP3_REG_PWR_CTRL = {:b}", result_buf[0]);
269 let mut pwr_ctrl: PWR_CTRL = PWR_CTRL(result_buf[0]);
270 debug!(" read PWR_CTRL reg = {:#b}", pwr_ctrl.0);
271 pwr_ctrl.set_temp_en(enable);
272
273 debug!(" writing PWR_CTRL reg = {:#b} or {:?}", pwr_ctrl.0, pwr_ctrl);
278
279 self.write_command([BMP3_REG_PWR_CTRL, pwr_ctrl.0]).await?;
288 self.delayer.delay_ms(20).await;
289 Ok(())
290 }
291
292 pub async fn set_bmp3_configuration(&mut self, config: Bmp3Configuration) -> Result<(), Error<E>> {
294 debug!("in set_bmp3_configuration({:?})", config);
296 self.set_power_control_mode(config.power_mode).await?;
298 debug!(" set_power_control_mode to {:?}", config.power_mode);
299 self.set_temperature_enable(config.temperature_enable).await?;
301 self.set_pressure_enable(config.pressure_enable).await?;
302 let osp: u8 = config.over_sampling_press as u8;
304 let ost: u8 = (config.over_sampling_temp as u8) << 3;
305 let osr: u8 = ost | osp;
306 debug!(" writing REG_OSR to {:#b}", osr);
307 self.write_command([BMP3_REG_OSR, osr]).await?;
308 self.delayer.delay_ms(20);
309 let odr: u8 = config.output_data_rate as u8;
311 debug!(" writing REG_ODR to {:#b}", odr);
312 self.write_command([BMP3_REG_ODR, odr]).await?;
313 self.delayer.delay_ms(20);
314 let iir_coef: u8 = (config.iir_filter_coef as u8) << 1;
316 debug!(" writing REG_CONFIG (IIR) to {:#b}", iir_coef);
317 self.write_command([BMP3_REG_CONFIG, iir_coef]).await?;
318 self.delayer.delay_ms(20).await;
319 Ok(())
320 }
321
322 pub async fn get_bmp3_configuration(&mut self) -> Result<Bmp3Configuration, Error<E>> {
324 debug!("in get_bmp3_configuration");
325 let mut result_buf: [u8; 7] = [0; 7];
326 self.read_register(BMP3_REG_INT_CTRL, &mut result_buf).await?;
328 debug!(" read config = {:?}", result_buf);
329 let _int_pin = result_buf[0];
330 let pwr_ctrl: PWR_CTRL = PWR_CTRL(result_buf[2]); debug!(" pwr_ctrl = {:?}", pwr_ctrl);
333 let pwr_mode = self.get_power_mode().await?; let temp_enable = pwr_ctrl.get_temp_en();
335 let press_enable = pwr_ctrl.get_press_en();
336 let osr_p = Over_Sampling::from(result_buf[3] & 0x07);
337 let osr_t = Over_Sampling::from((result_buf[3] & 0x38) >> 3);
339 let odr: Odr = Odr::from(result_buf[4] & 0x3f);
341 let iir_filter = FilterCoef::from(result_buf[6]>>1);
343 Ok(Bmp3Configuration {
346 power_mode: pwr_mode,
347 temperature_enable: temp_enable,
348 pressure_enable: press_enable,
349 over_sampling_temp: osr_t,
350 over_sampling_press: osr_p,
351 output_data_rate: odr,
352 iir_filter_coef: iir_filter,
353 })
354
355 }
356
357
358
359 pub async fn set_interrupt_pin_config(&mut self, intpin_config: InterruptPinControl) -> Result<(), Error<E>> {
361 debug!("in set_interrupt_pin_config()");
362 let status = self.get_status().await?;
363 if (status.get_cmd_ready()) {
364 self.write_command([BMP3_REG_INT_CTRL, intpin_config.0] ).await?;
365 self.delayer.delay_ms(20);
366 Ok(())
367 } else {
368 Err(Error::NotReadyForCommand)
369 }
370 }
371
372 pub async fn get_interrupt_pin_configuration(&mut self) -> Result<InterruptPinControl, Error<E>> {
374 debug!("in get_interrupt_pin_configuration");
375 let mut result_buf: [u8; 1] = [0; 1];
376 self.read_register(BMP3_REG_INT_CTRL, &mut result_buf).await?;
377 info!(" raw value is {:b}", result_buf[0]);
378 Ok(InterruptPinControl(result_buf[0]))
379 }
380
381
382 pub async fn get_interrupt_status(&mut self) -> Result<IntStatus, Error<E>> {
384 debug!("in get_interrupt_status");
385 let mut result_buf: [u8; 1] = [0; 1];
386 self.read_register(BMP3_REG_INT_STATUS, &mut result_buf).await?;
387 Ok(IntStatus(result_buf[0]))
388 }
389
390 pub async fn read_calibration_pars(&mut self) -> Result<(), Error<E>> {
392 let mut result_buf: [u8; 21] = [0; 21];
393 self.read_register(BMP3_REG_CALIB_DATA+1, &mut result_buf).await;
394
395 let nvm_par_t1: u16 = result_buf[0] as u16 | ( (result_buf[1] as u16) << 8 );
396 let nvm_par_t2: u16 = result_buf[2] as u16 | ( (result_buf[3] as u16) << 8 );
397 let nvm_par_t3: i8 = result_buf[4] as i8;
398 self.cal_pars.par_t1_f = (nvm_par_t1 as f64) / 0.003_906_25;
400 self.cal_pars.par_t2_f = (nvm_par_t2 as f64) / 1_073_741_824.0;
401 self.cal_pars.par_t3_f = (nvm_par_t3 as f64) / 281_474_976_710_656.0;
402
403 let nvm_par_p1: i16 = ( (result_buf[6] as i16) << 8 ) | result_buf[5] as i16 ;
404 let nvm_par_p2: i16 = ( (result_buf[8] as i16) << 8 ) | result_buf[7] as i16 ;
405 let nvm_par_p3: i8 = result_buf[9] as i8;
406 let nvm_par_p4: i8 = result_buf[10] as i8;
407 let nvm_par_p5: u16 = ( (result_buf[12] as u16) << 8 ) | result_buf[11] as u16 ;
408 let nvm_par_p6: u16 = ( (result_buf[14] as u16) << 8 ) | result_buf[13] as u16 ;
409
410
411 let nvm_par_p7: i8 = result_buf[15] as i8;
412 let nvm_par_p8: i8 = result_buf[16] as i8;
413 let nvm_par_p9: i16 = ( (result_buf[18] as i16) << 8 ) | result_buf[17] as i16 ;
414 let nvm_par_p10: i8 = result_buf[19] as i8;
415 let nvm_par_p11: i8 = result_buf[20] as i8;
416
417 self.cal_pars.par_p1_f = (nvm_par_p1 as f64 - 16384.0) / 1048576.0;
431 self.cal_pars.par_p2_f = (nvm_par_p2 as f64 - 16384.0) / 536870912.0;
432 self.cal_pars.par_p3_f = (nvm_par_p3 as f64) / 4294967296.0;
433 self.cal_pars.par_p4_f = (nvm_par_p4 as f64) / 137438953472.0;
434 self.cal_pars.par_p5_f = (nvm_par_p5 as f64) / 0.125;
435 self.cal_pars.par_p6_f = (nvm_par_p6 as f64) / 64.0;
436 self.cal_pars.par_p7_f = (nvm_par_p7 as f64) / 256.0;
437 self.cal_pars.par_p8_f = (nvm_par_p8 as f64) / 32768.0;
438 self.cal_pars.par_p9_f = (nvm_par_p9 as f64) / 281474976710656.0;
439 self.cal_pars.par_p10_f = (nvm_par_p10 as f64) / 281474976710656.0;
440 self.cal_pars.par_p11_f = (nvm_par_p11 as f64) / 36893488147419103232.0;
441
442 Ok(())
443 }
444
445 pub fn compensate_temperature(&self, raw_temperature: u32) -> f64 {
446 let temp_1 = (raw_temperature as f64) - self.cal_pars.par_t1_f;
447 let temp_2 = (temp_1 as f64) * self.cal_pars.par_t2_f;
448 let temperature = temp_2 + (temp_1 * temp_1) * self.cal_pars.par_t3_f;
449
450 temperature
453 }
454
455 pub fn compensate_pressure(&self, raw_pressure: f64, temperature: f64) -> f64 {
456 debug!("in compensate_pressure({})", temperature);
457 let calc_part1 = self.cal_pars.par_p6_f * temperature;
460 let calc_part2 = self.cal_pars.par_p7_f * (temperature * temperature);
461 let calc_part3 = self.cal_pars.par_p8_f * (temperature * temperature * temperature);
462 let partial_1 = self.cal_pars.par_p5_f + calc_part1 + calc_part2 + calc_part3;
463 debug!(" partial_1 _out1 = {}", partial_1);
464
465 let calc_part1 = self.cal_pars.par_p2_f * temperature;
466 let calc_part2 = self.cal_pars.par_p3_f * (temperature * temperature);
467
468 let calc_part3 = self.cal_pars.par_p4_f * (temperature * temperature * temperature);
469 let partial_2 = raw_pressure * ( self.cal_pars.par_p1_f + calc_part1 + calc_part2 + calc_part3);
470 debug!(" partial_2 out2= {}", partial_2);
471
472 let calc_part1 = raw_pressure * raw_pressure ;
473 let calc_part2 = self.cal_pars.par_p9_f + self.cal_pars.par_p10_f * temperature;
474 let calc_part3 = calc_part1 * calc_part2;
475
476 let partial_3 = calc_part3 + (raw_pressure * raw_pressure * raw_pressure) * self.cal_pars.par_p11_f;
477 debug!(" partial_3 partial_data4 = {}", partial_3);
478
479 partial_1 + partial_2 + partial_3
480
481
482
483
484 }
485 pub fn get_sealevel_airpressure(&self, air_pressure: f64, temperature: f64, altitude_m: f64) -> f64 {
487
488 let exponent = -9.80665 * 0.028964 * altitude_m / (8.31432 * (temperature + 273.15));
489 let base: f64 = 2.71828175f64;
490 let air_press_at_sealevel = (air_pressure / 100.0) / pow(base, exponent) * 100.00;
491 air_press_at_sealevel
493 }
494
495 pub async fn read_measurements_with_altitude(&mut self, altitude: f64) -> Result<Measurements, Error<E>> {
497 debug!("in read_measurements_with_altitude");
498 let mut result_buf: [u8; 6] = [0; 6];
499 let command_buf: [u8; 1] = [BMP3_REG_PRESS_DATA];
500 self.read_register(BMP3_REG_PRESS_DATA, &mut result_buf).await?;
504 let raw_pressure = result_buf[0] as u32 | ((result_buf[1] as u32) << 8) | (result_buf[2] as u32) << 16;
505 let raw_temperature = result_buf[3] as u32 | ((result_buf[4] as u32) << 8) | (result_buf[5] as u32) << 16;
506 debug!(" read_measurement_with..");
507 debug!(" raw_pressure = {:?}", raw_pressure);
508 let compensated_temp = self.compensate_temperature(raw_temperature);
511 let compensated_press = self.compensate_pressure(raw_pressure as f64, compensated_temp as f64);
512
513 let sealevel_press = self.get_sealevel_airpressure(compensated_press as f64, compensated_temp, altitude);
514 self.altitude_m = altitude;
515
516 Ok(Measurements { temperature_c: compensated_temp, air_pressure_pa: compensated_press ,
517 air_pressure_sealevel_pa: sealevel_press })
518
519 }
520
521 pub async fn read_measurements(&mut self) -> Result<Measurements, Error<E>> {
523 debug!("in read_measurements");
524 let mut result_buf: [u8; 6] = [0; 6];
525 let command_buf: [u8; 1] = [BMP3_REG_PRESS_DATA];
526 self.i2c
527 .write_read(self.address, &command_buf, &mut result_buf).await
528 .map_err(Error::I2c)?;
529 let raw_pressure = result_buf[0] as u32 | ((result_buf[1] as u32) << 8) | (result_buf[2] as u32) << 16;
530 let raw_temperature = result_buf[3] as u32 | ((result_buf[4] as u32) << 8) | (result_buf[5] as u32) << 16;
531
532 let compensated_temp = self.compensate_temperature(raw_temperature);
533 let compensated_press = self.compensate_pressure(raw_pressure as f64, compensated_temp as f64);
534
535 let sealevel_press = self.get_sealevel_airpressure(compensated_press, compensated_temp, self.altitude_m);
536
537 Ok(Measurements { temperature_c: compensated_temp, air_pressure_pa: compensated_press ,
538 air_pressure_sealevel_pa: sealevel_press })
539
540
541
542 }
543
544 pub async fn get_power_mode(&mut self) -> Result<PowerMode, Error<E>> {
546 debug!("in get_power_control_mode");
547 let mut result_buf: [u8; 1] = [ 0; 1];
548 self.read_register(BMP3_REG_PWR_CTRL, &mut result_buf).await?;
549 debug!(" get_power_control_mode = {:#b}", result_buf[0] & 0b110000 >> 4);
550 Ok(PowerMode::from(result_buf[0] & 0b110000 >> 4))
551 }
552
553 pub async fn set_power_control_mode(&mut self, pwr_mode: PowerMode) -> Result<(), Error<E>> {
555 debug!("in set_power_control_mode");
556 let mut result_buf: [u8; 1] = [0; 1];
557 let mut command_buf: [u8; 1] = [0; 1];
558 self.read_register(BMP3_REG_PWR_CTRL, &mut result_buf).await?;
560 command_buf[0] = ((pwr_mode as u8) << 4) | (result_buf[0] & 0x03); self.write_command( [BMP3_REG_PWR_CTRL, command_buf[0]] ).await?;
562 self.delayer.delay_ms(10).await;
563 debug!(" set_power_control_mode(), writing PWR_CTRL reg = {:?} ({:#b})", pwr_mode, command_buf[0]);
564 Ok(())
565
566
567 }
568
569 pub async fn set_fifo_config(&mut self, fifo_config: Fifo_Config) -> Result<(), Error<E>> {
571 debug!("in set_fifo_config");
572 self.write_command([BMP3_REG_FIFO_CONFIG_1, fifo_config.fifo_config_1.0] ).await?;
573 self.delayer.delay_ms(5);
574 self.write_command([BMP3_REG_FIFO_CONFIG_2, fifo_config.fifo_config_2.0] ).await?;
575 self.fifo_config = fifo_config;
576
577 Ok(())
578 }
579
580 pub async fn get_fifo_config(&mut self) -> Result<Fifo_Config, Error<E>> {
582 debug!("in get_fifo_config");
583 let mut result_buf: [u8; 2] = [0; 2];
584 self.read_register(BMP3_REG_FIFO_CONFIG_1, &mut result_buf).await?;
585 debug!(" result_buf[0] = {:#b}", result_buf[0]);
586 debug!(" result_buf[1] = {:#b}", result_buf[1]);
587
588 let config_1s: FifoConfig1 = FifoConfig1(result_buf[0]); self.fifo_config.fifo_config_1 = config_1s; let config_1: FifoConfig1 = FifoConfig1(result_buf[0]);
591 debug!(" config_1 = {:?}", config_1);
592
593 self.delayer.delay_ms(5);
594 let config_2s: FifoConfig2 = FifoConfig2(result_buf[1]); self.fifo_config.fifo_config_2 = config_2s; let config_2: FifoConfig2 = FifoConfig2(result_buf[1]);
597
598 debug!(" config_2 = {:?}", config_2);
599 let fifo_config: Fifo_Config = Fifo_Config { fifo_config_1: config_1, fifo_config_2: config_2 };
600
601 Ok(fifo_config)
602
603 }
604
605 pub async fn fifo_set_watermark_frames(&mut self, frames: u16) -> Result<(), Error<E>> {
607 let length_bytes = self.get_fifo_frames_to_bytes(frames);
608 if (length_bytes > 0) {
609 let length: [u8; 2] = length_bytes.to_le_bytes();
610 self.write_command([BMP3_REG_FIFO_WM, length[0], length[1]]).await?;
611
612 } else {
613 return Err(Error::CommandError);
614 }
615 Ok(())
616 }
617
618 fn get_fifo_frames_to_bytes(&self, num_frames: u16) -> u16 {
619 let mut wm_length: u16 = 0;
620 if ((num_frames == 0) || (num_frames > 73)) {
621 wm_length = 0;
622
623 } else {
624 if (self.fifo_config.fifo_config_1.get_fifo_temp_enable() && (self.fifo_config.fifo_config_1.get_fifo_press_enable())) {
625 wm_length = num_frames * 7 ; } else if ( (self.fifo_config.fifo_config_1.get_fifo_temp_enable()) ||
627 (self.fifo_config.fifo_config_1.get_fifo_press_enable()) ) {
628 wm_length = num_frames * 4; }
630 return wm_length;
631 }
632
633 return wm_length;
634 }
635
636 pub fn get_fifo_watermark_in_frames(&mut self) -> Result<u16, Error<E>> {
637 let mut result_buf: [u8; 2] = [0; 2];
638 self.read_register(BMP3_REG_FIFO_WM, &mut result_buf).await?;
639 let length:u16 = u16::from_le_bytes(result_buf);
640 let mut wm_frames : u16 = 0;
641 if length < 4 {
642 return Ok(0);
643 } else {
644 if (self.fifo_config.fifo_config_1.get_fifo_temp_enable() && (self.fifo_config.fifo_config_1.get_fifo_press_enable())) {
645 wm_frames = length / 7 ; } else if ( (self.fifo_config.fifo_config_1.get_fifo_temp_enable()) ||
647 (self.fifo_config.fifo_config_1.get_fifo_press_enable()) ) {
648 wm_frames = length / 4; }
650 }
651
652 return (Ok(wm_frames));
653 }
654
655 pub async fn fifo_flush(&mut self) -> Result<(), Error<E>> {
657 debug!("in fifo_flush");
658 let mut result_buf: [u8; 1] = [0; 1];
660 let status = self.get_status().await?;
661 if (status.get_cmd_ready()) {
662 self.write_command([BMP3_REG_CMD, BMP3_FIFO_FLUSH]).await?;
664
665 self.delayer.delay_ms(5).await;
670 self.read_register(BMP3_REG_ERR, &mut result_buf).await?;
671 let error_value = ErrorReg(result_buf[0]);
672 debug!(" write CMD returned {:x}", result_buf[0]);
673 if ( error_value.get_cfg_error() || error_value.get_cmd_error() || error_value.get_fatal_error() ) {
674 return Err(Error::CommandError);
675 }
676 return Ok(());
677 }
678 Err(Error::NotReadyForCommand)
679
680 }
681
682 pub async fn get_fifo_number_frames(&mut self) -> Result<u16, Error<E>> {
684 debug!("in get_fifo_number_frames");
685 let mut result_buf: [u8; 2] = [ 0; 2];
686 self.read_register(BMP3_REG_FIFO_LENGTH, &mut result_buf).await?; let fifo_length_bytes: u16 = u16::from_le_bytes(result_buf);
688 debug!(" fifo_length_bytes = {}", fifo_length_bytes);
689 let bytes_per_frame: u16 = 1 + 3 * (self.fifo_config.fifo_config_1.get_fifo_press_enable() as u16 +
693 self.fifo_config.fifo_config_1.get_fifo_temp_enable() as u16);
694
695 Ok(fifo_length_bytes / bytes_per_frame)
697 }
698
699 pub async fn get_fifo_frame(&mut self) -> Result<FifoFrame, Error<E>> {
701 debug!("in get_fifo_frame");
702 let mut result_buf: [u8; 1] = [0; 1];
703 self.read_register(BMP3_REG_FIFO_DATA, &mut result_buf).await?; let fh = result_buf[0];
710 debug!(" header = {:b}", fh);
711 if (fh & 0b1000_0000 != 0x00) {
712 if (fh & 0x20 == 0x20) { debug!(" a time frame");
716 let mut result_buf: [u8; 4] = [0; 4];
717 self.read_register(BMP3_REG_FIFO_DATA, &mut result_buf).await?;
718 let time_stamp: u32 = u32::from_le_bytes([result_buf[1], result_buf[2], result_buf[3], 0]);
719 return Ok( FifoFrame::SensorDataFrame(SensorFrameEnum::Time(time_stamp)) )
720
721 } else if (fh & 0x14 == 0x14) { debug!(" a temperature and pressure frame");
724 let mut result_buf: [u8; 7] = [0; 7];
725 self.read_register(BMP3_REG_FIFO_DATA, &mut result_buf).await?;
726 let raw_temperature = result_buf[1] as u32 | ((result_buf[2] as u32) << 8) | (result_buf[3] as u32) << 16;
727 let compensated_temp = self.compensate_temperature(raw_temperature);
728 let raw_pressure: u32 = result_buf[4] as u32 | ((result_buf[5] as u32) << 8) | (result_buf[6] as u32) << 16;
729 let compensated_press = self.compensate_pressure(raw_pressure as f64, compensated_temp);
730 let tandP: TandPtype = TandPtype{temperature: compensated_temp, pressure: compensated_press };
731 return Ok( FifoFrame::SensorDataFrame(SensorFrameEnum::TemperatureAndPressureData(tandP)) )
732
733 } else if (fh & 0x10 == 0x10) { debug!(" a temperature frame");
735 let mut result_buf: [u8; 4] = [0; 4];
736 self.read_register(BMP3_REG_FIFO_DATA, &mut result_buf).await?;
737 let raw_temperature = result_buf[1] as u32 | ((result_buf[2] as u32) << 8) | (result_buf[3] as u32) << 16;
738 let compensated_temp = self.compensate_temperature(raw_temperature);
739 return Ok( FifoFrame::SensorDataFrame(SensorFrameEnum::TemperatureData(compensated_temp)) )
740
741 } else if (fh & 0x04 == 0x04) { debug!(" a pressure frame");
743 let mut result_buf: [u8; 4] = [0; 4];
744 self.read_register(BMP3_REG_FIFO_DATA, &mut result_buf).await?;
745 let raw_pressure: u32 = result_buf[1] as u32 | ((result_buf[2] as u32) << 8) | (result_buf[3] as u32) << 16;
746
747 let compensated_press = self.compensate_pressure(raw_pressure as f64, 0.0); return Ok( FifoFrame::SensorDataFrame(SensorFrameEnum::PressureData(compensated_press)) )
749
750
751 } else {
752 debug!(" an empty frame");
753 return Ok(FifoFrame::SensorDataFrame(SensorFrameEnum::Empty))
754 }
755
756
757 }
758 else if (fh & 0b01000000 != 0x00) {
759 debug!(" a control frame");
761 let mut result_buf: [u8; 2] = [ 0; 2];
762 self.read_register(BMP3_REG_FIFO_DATA, &mut result_buf).await?; if (fh & 0b01000100 == 0x44) {
764 debug!(" a configuration error");
766 return Ok(FifoFrame::ControlFrame(ControlFrameEnum::ConfigurationError))
767
768 } else if (fh & 0b01001000 == 0x48) {
769 debug!(" a configuration change");
770 return Ok(FifoFrame::ControlFrame(ControlFrameEnum::ConfigurationChange))
771 } else {
772 debug!(" an unknown control frame, header = {:x}", fh);
773 return Err(Error::FifoUnknownContent)
774 }
775 } else {
776 return Err(Error::FifoUnknownContent)
777 }
778
779
780 }
783
784
785
786}