refactor: format code
This commit is contained in:
parent
432d3643c7
commit
cf9b0fbdd0
5 changed files with 165 additions and 89 deletions
|
@ -1,17 +1,15 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
|
use bme680::i2c::Address;
|
||||||
use bme680::{Bme680, Bme680Error, IIRFilterSize, OversamplingSetting, PowerMode, SettingsBuilder};
|
use bme680::{Bme680, Bme680Error, IIRFilterSize, OversamplingSetting, PowerMode, SettingsBuilder};
|
||||||
use core::time::Duration;
|
use core::time::Duration;
|
||||||
use embedded_hal::delay::DelayNs;
|
use embedded_hal::delay::DelayNs;
|
||||||
use linux_embedded_hal as hal;
|
use linux_embedded_hal as hal;
|
||||||
use linux_embedded_hal::Delay;
|
use linux_embedded_hal::Delay;
|
||||||
use log::info;
|
use log::info;
|
||||||
use bme680::i2c::Address;
|
|
||||||
|
|
||||||
|
|
||||||
// Please export RUST_LOG=info in order to see logs in the console.
|
// Please export RUST_LOG=info in order to see logs in the console.
|
||||||
fn main() -> Result<(), Bme680Error>
|
fn main() -> Result<(), Bme680Error> {
|
||||||
{
|
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
|
|
||||||
let i2c = hal::I2cdev::new("/dev/i2c-1").unwrap();
|
let i2c = hal::I2cdev::new("/dev/i2c-1").unwrap();
|
||||||
|
|
|
@ -9,14 +9,23 @@ impl Calculation {
|
||||||
/// * `calibration_data` - The calibration data of the sensor.
|
/// * `calibration_data` - The calibration data of the sensor.
|
||||||
/// * `ambient_temperature` - The ambient temperature.
|
/// * `ambient_temperature` - The ambient temperature.
|
||||||
/// * `heater_temperature` - The heater temperature.
|
/// * `heater_temperature` - The heater temperature.
|
||||||
pub fn heater_resistance(calibration_data: &CalibrationData, ambient_temperature: i8, heater_temperature: u16) -> u8 {
|
pub fn heater_resistance(
|
||||||
|
calibration_data: &CalibrationData,
|
||||||
|
ambient_temperature: i8,
|
||||||
|
heater_temperature: u16,
|
||||||
|
) -> u8 {
|
||||||
// cap temperature
|
// cap temperature
|
||||||
let temp = if heater_temperature <= 400 { heater_temperature } else { 400 };
|
let temp = if heater_temperature <= 400 {
|
||||||
|
heater_temperature
|
||||||
|
} else {
|
||||||
|
400
|
||||||
|
};
|
||||||
|
|
||||||
let var1 = ambient_temperature as i32 * calibration_data.par_gh3 as i32 / 1000i32 * 256i32;
|
let var1 = ambient_temperature as i32 * calibration_data.par_gh3 as i32 / 1000i32 * 256i32;
|
||||||
let var2 = (calibration_data.par_gh1 as i32 + 784i32)
|
let var2 = (calibration_data.par_gh1 as i32 + 784i32)
|
||||||
* (((calibration_data.par_gh2 as i32 + 154009i32) * temp as i32 * 5i32 / 100i32 + 3276800i32)
|
* (((calibration_data.par_gh2 as i32 + 154009i32) * temp as i32 * 5i32 / 100i32
|
||||||
/ 10i32);
|
+ 3276800i32)
|
||||||
|
/ 10i32);
|
||||||
let var3 = var1 + var2 / 2i32;
|
let var3 = var1 + var2 / 2i32;
|
||||||
let var4 = var3 / (calibration_data.res_heat_range as i32 + 4i32);
|
let var4 = var3 / (calibration_data.res_heat_range as i32 + 4i32);
|
||||||
let var5 = 131i32 * calibration_data.res_heat_val as i32 + 65536i32;
|
let var5 = 131i32 * calibration_data.res_heat_val as i32 + 65536i32;
|
||||||
|
@ -81,10 +90,12 @@ impl Calculation {
|
||||||
/// * `pressure_adc` - The pressure value as returned by the analog to digital converter.
|
/// * `pressure_adc` - The pressure value as returned by the analog to digital converter.
|
||||||
pub fn pressure(calibration_data: &CalibrationData, t_fine: i32, pressure_adc: u32) -> u32 {
|
pub fn pressure(calibration_data: &CalibrationData, t_fine: i32, pressure_adc: u32) -> u32 {
|
||||||
let mut var1: i32 = (t_fine >> 1) - 64000;
|
let mut var1: i32 = (t_fine >> 1) - 64000;
|
||||||
let mut var2: i32 = ((((var1 >> 2) * (var1 >> 2)) >> 11) * calibration_data.par_p6 as i32) >> 2;
|
let mut var2: i32 =
|
||||||
|
((((var1 >> 2) * (var1 >> 2)) >> 11) * calibration_data.par_p6 as i32) >> 2;
|
||||||
var2 += (var1 * (calibration_data.par_p5 as i32)) << 1;
|
var2 += (var1 * (calibration_data.par_p5 as i32)) << 1;
|
||||||
var2 = (var2 >> 2i32) + ((calibration_data.par_p4 as i32) << 16i32);
|
var2 = (var2 >> 2i32) + ((calibration_data.par_p4 as i32) << 16i32);
|
||||||
var1 = (((((var1 >> 2i32) * (var1 >> 2i32)) >> 13i32) * ((calibration_data.par_p3 as i32) << 5i32))
|
var1 = (((((var1 >> 2i32) * (var1 >> 2i32)) >> 13i32)
|
||||||
|
* ((calibration_data.par_p3 as i32) << 5i32))
|
||||||
>> 3i32)
|
>> 3i32)
|
||||||
+ ((calibration_data.par_p2 as i32 * var1) >> 1i32);
|
+ ((calibration_data.par_p2 as i32 * var1) >> 1i32);
|
||||||
var1 >>= 18i32;
|
var1 >>= 18i32;
|
||||||
|
@ -120,8 +131,10 @@ impl Calculation {
|
||||||
- ((temp_scaled * calibration_data.par_h3 as i32 / 100i32) >> 1i32);
|
- ((temp_scaled * calibration_data.par_h3 as i32 / 100i32) >> 1i32);
|
||||||
let var2: i32 = (calibration_data.par_h2 as i32
|
let var2: i32 = (calibration_data.par_h2 as i32
|
||||||
* (temp_scaled * calibration_data.par_h4 as i32 / 100i32
|
* (temp_scaled * calibration_data.par_h4 as i32 / 100i32
|
||||||
+ ((temp_scaled * (temp_scaled * calibration_data.par_h5 as i32 / 100i32)) >> 6i32) / 100i32
|
+ ((temp_scaled * (temp_scaled * calibration_data.par_h5 as i32 / 100i32))
|
||||||
+ (1i32 << 14i32)))
|
>> 6i32)
|
||||||
|
/ 100i32
|
||||||
|
+ (1i32 << 14i32)))
|
||||||
>> 10i32;
|
>> 10i32;
|
||||||
let var3: i32 = var1 * var2;
|
let var3: i32 = var1 * var2;
|
||||||
let var4: i32 = (calibration_data.par_h6 as i32) << 7i32;
|
let var4: i32 = (calibration_data.par_h6 as i32) << 7i32;
|
||||||
|
@ -141,7 +154,11 @@ impl Calculation {
|
||||||
///
|
///
|
||||||
/// * `gas_resistance_adc` - The gas resistance reading from the analog to digital converter.
|
/// * `gas_resistance_adc` - The gas resistance reading from the analog to digital converter.
|
||||||
/// * `gas_range` - The lookup table gas range.
|
/// * `gas_range` - The lookup table gas range.
|
||||||
pub fn gas_resistance(calibration_data: &CalibrationData, gas_resistance_adc: u16, gas_range: u8) -> u32 {
|
pub fn gas_resistance(
|
||||||
|
calibration_data: &CalibrationData,
|
||||||
|
gas_resistance_adc: u16,
|
||||||
|
gas_range: u8,
|
||||||
|
) -> u32 {
|
||||||
let lookup_table1: [u32; 16] = [
|
let lookup_table1: [u32; 16] = [
|
||||||
2147483647u32,
|
2147483647u32,
|
||||||
2147483647u32,
|
2147483647u32,
|
||||||
|
|
26
src/i2c.rs
26
src/i2c.rs
|
@ -1,6 +1,6 @@
|
||||||
use embedded_hal::i2c::I2c;
|
|
||||||
use crate::Bme680Error;
|
use crate::Bme680Error;
|
||||||
use crate::Bme680Error::{I2CRead, I2CWrite};
|
use crate::Bme680Error::{I2CRead, I2CWrite};
|
||||||
|
use embedded_hal::i2c::I2c;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Represents the I2C address of the BME680 Sensor.
|
/// Represents the I2C address of the BME680 Sensor.
|
||||||
|
@ -40,11 +40,12 @@ impl I2CUtility {
|
||||||
i2c_handle: &mut I2C,
|
i2c_handle: &mut I2C,
|
||||||
device_address: u8,
|
device_address: u8,
|
||||||
register_address: u8,
|
register_address: u8,
|
||||||
) -> Result<u8, Bme680Error>
|
) -> Result<u8, Bme680Error> {
|
||||||
{
|
|
||||||
let mut buf = [0; 1];
|
let mut buf = [0; 1];
|
||||||
|
|
||||||
i2c_handle.write(device_address, &[register_address]).map_err(|_e| { I2CWrite })?;
|
i2c_handle
|
||||||
|
.write(device_address, &[register_address])
|
||||||
|
.map_err(|_e| I2CWrite)?;
|
||||||
|
|
||||||
match i2c_handle.read(device_address, &mut buf) {
|
match i2c_handle.read(device_address, &mut buf) {
|
||||||
Ok(()) => Ok(buf[0]),
|
Ok(()) => Ok(buf[0]),
|
||||||
|
@ -58,9 +59,10 @@ impl I2CUtility {
|
||||||
device_address: u8,
|
device_address: u8,
|
||||||
register_address: u8,
|
register_address: u8,
|
||||||
buffer: &mut [u8],
|
buffer: &mut [u8],
|
||||||
) -> Result<(), Bme680Error>
|
) -> Result<(), Bme680Error> {
|
||||||
{
|
i2c_handle
|
||||||
i2c_handle.write(device_address, &[register_address]).map_err(|_e| { I2CWrite })?;
|
.write(device_address, &[register_address])
|
||||||
|
.map_err(|_e| I2CWrite)?;
|
||||||
|
|
||||||
match i2c_handle.read(device_address, buffer) {
|
match i2c_handle.read(device_address, buffer) {
|
||||||
Ok(()) => Ok(()),
|
Ok(()) => Ok(()),
|
||||||
|
@ -69,7 +71,13 @@ impl I2CUtility {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Writes bytes to the I2C bus.
|
/// Writes bytes to the I2C bus.
|
||||||
pub fn write_bytes<I2C: I2c>(i2c_handle: &mut I2C, device_address: u8, buffer: &[u8]) -> Result<(), Bme680Error> {
|
pub fn write_bytes<I2C: I2c>(
|
||||||
i2c_handle.write(device_address, &buffer).map_err(|_e| { I2CWrite })
|
i2c_handle: &mut I2C,
|
||||||
|
device_address: u8,
|
||||||
|
buffer: &[u8],
|
||||||
|
) -> Result<(), Bme680Error> {
|
||||||
|
i2c_handle
|
||||||
|
.write(device_address, &buffer)
|
||||||
|
.map_err(|_e| I2CWrite)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
165
src/lib.rs
165
src/lib.rs
|
@ -5,7 +5,6 @@
|
||||||
//! In the examples you can find a demo how to use the library in Linux using the linux-embedded-hal crate (e.g. on a RPI).
|
//! In the examples you can find a demo how to use the library in Linux using the linux-embedded-hal crate (e.g. on a RPI).
|
||||||
//! ```no_run
|
//! ```no_run
|
||||||
|
|
||||||
|
|
||||||
//! use bme680::{Bme680, Bme680Error, IIRFilterSize, OversamplingSetting, PowerMode, SettingsBuilder};
|
//! use bme680::{Bme680, Bme680Error, IIRFilterSize, OversamplingSetting, PowerMode, SettingsBuilder};
|
||||||
//! use core::time::Duration;
|
//! use core::time::Duration;
|
||||||
//! use embedded_hal::delay::DelayNs;
|
//! use embedded_hal::delay::DelayNs;
|
||||||
|
@ -65,27 +64,27 @@
|
||||||
#![forbid(unsafe_code)]
|
#![forbid(unsafe_code)]
|
||||||
|
|
||||||
pub use self::settings::{
|
pub use self::settings::{
|
||||||
DesiredSensorSettings, GasSettings, IIRFilterSize, OversamplingSetting, SensorSettings, Settings,
|
DesiredSensorSettings, GasSettings, IIRFilterSize, OversamplingSetting, SensorSettings,
|
||||||
SettingsBuilder, TemperatureSettings,
|
Settings, SettingsBuilder, TemperatureSettings,
|
||||||
};
|
};
|
||||||
|
|
||||||
mod calculation;
|
mod calculation;
|
||||||
mod settings;
|
|
||||||
pub mod i2c;
|
pub mod i2c;
|
||||||
|
mod settings;
|
||||||
|
|
||||||
use crate::calculation::Calculation;
|
use crate::calculation::Calculation;
|
||||||
use crate::hal::delay::DelayNs;
|
use crate::hal::delay::DelayNs;
|
||||||
use crate::hal::i2c::I2c;
|
use crate::hal::i2c::I2c;
|
||||||
|
|
||||||
use core::time::Duration;
|
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
use core::time::Duration;
|
||||||
use embedded_hal as hal;
|
use embedded_hal as hal;
|
||||||
use log::{debug, error, info};
|
use log::{debug, error, info};
|
||||||
|
|
||||||
|
use crate::Bme680Error::{I2CRead, I2CWrite};
|
||||||
|
use i2c::{Address, I2CUtility};
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use i2c::{Address, I2CUtility};
|
|
||||||
use crate::Bme680Error::{I2CRead, I2CWrite};
|
|
||||||
|
|
||||||
/// BME680 General config
|
/// BME680 General config
|
||||||
pub const BME680_POLL_PERIOD_MS: u8 = 10;
|
pub const BME680_POLL_PERIOD_MS: u8 = 10;
|
||||||
|
@ -342,8 +341,7 @@ fn boundary_check_u8(
|
||||||
value_name: &'static str,
|
value_name: &'static str,
|
||||||
min: u8,
|
min: u8,
|
||||||
max: u8,
|
max: u8,
|
||||||
) -> Result<u8, Bme680Error<>>
|
) -> Result<u8, Bme680Error> {
|
||||||
{
|
|
||||||
let value = value.ok_or(Bme680Error::BoundaryCheckFailure(value_name))?;
|
let value = value.ok_or(Bme680Error::BoundaryCheckFailure(value_name))?;
|
||||||
|
|
||||||
if value < min {
|
if value < min {
|
||||||
|
@ -361,9 +359,9 @@ fn boundary_check_u8(
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I2C: I2c, D: DelayNs> Bme680<I2C, D>
|
impl<I2C: I2c, D: DelayNs> Bme680<I2C, D>
|
||||||
where
|
where
|
||||||
D: DelayNs,
|
D: DelayNs,
|
||||||
I2C: I2c,
|
I2C: I2c,
|
||||||
{
|
{
|
||||||
/// Sends the soft reset command to the chip.
|
/// Sends the soft reset command to the chip.
|
||||||
pub fn soft_reset(
|
pub fn soft_reset(
|
||||||
|
@ -387,12 +385,17 @@ impl<I2C: I2c, D: DelayNs> Bme680<I2C, D>
|
||||||
|
|
||||||
debug!("Reading chip id");
|
debug!("Reading chip id");
|
||||||
/* Soft reset to restore it to default values*/
|
/* Soft reset to restore it to default values*/
|
||||||
let chip_id = I2CUtility::read_byte::<I2C>(&mut i2c_handle, device_address.addr(), BME680_CHIP_ID_ADDR)?;
|
let chip_id = I2CUtility::read_byte::<I2C>(
|
||||||
|
&mut i2c_handle,
|
||||||
|
device_address.addr(),
|
||||||
|
BME680_CHIP_ID_ADDR,
|
||||||
|
)?;
|
||||||
debug!("Chip id: {}", chip_id);
|
debug!("Chip id: {}", chip_id);
|
||||||
|
|
||||||
if chip_id == BME680_CHIP_ID {
|
if chip_id == BME680_CHIP_ID {
|
||||||
debug!("Reading calibration data");
|
debug!("Reading calibration data");
|
||||||
let calibration_data = Bme680::<I2C, D>::get_calib_data::<I2C>(&mut i2c_handle, device_address)?;
|
let calibration_data =
|
||||||
|
Bme680::<I2C, D>::get_calib_data::<I2C>(&mut i2c_handle, device_address)?;
|
||||||
debug!("Calibration data {:?}", calibration_data);
|
debug!("Calibration data {:?}", calibration_data);
|
||||||
let device = Bme680 {
|
let device = Bme680 {
|
||||||
i2c_bus_handle: i2c_handle,
|
i2c_bus_handle: i2c_handle,
|
||||||
|
@ -411,10 +414,7 @@ impl<I2C: I2c, D: DelayNs> Bme680<I2C, D>
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the sensor registers.
|
/// Sets the sensor registers.
|
||||||
fn bme680_set_registers(
|
fn bme680_set_registers(&mut self, registers: &[(u8, u8)]) -> Result<(), Bme680Error> {
|
||||||
&mut self,
|
|
||||||
registers: &[(u8, u8)],
|
|
||||||
) -> Result<(), Bme680Error> {
|
|
||||||
if registers.is_empty() || registers.len() > (BME680_TMP_BUFFER_LENGTH / 2) as usize {
|
if registers.is_empty() || registers.len() > (BME680_TMP_BUFFER_LENGTH / 2) as usize {
|
||||||
return Err(Bme680Error::InvalidLength);
|
return Err(Bme680Error::InvalidLength);
|
||||||
}
|
}
|
||||||
|
@ -427,7 +427,7 @@ impl<I2C: I2c, D: DelayNs> Bme680<I2C, D>
|
||||||
);
|
);
|
||||||
self.i2c_bus_handle
|
self.i2c_bus_handle
|
||||||
.write(self.device_address.addr(), &buffer)
|
.write(self.device_address.addr(), &buffer)
|
||||||
.map_err(|_e| { I2CWrite })?;
|
.map_err(|_e| I2CWrite)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -443,7 +443,10 @@ impl<I2C: I2c, D: DelayNs> Bme680<I2C, D>
|
||||||
let tph_sett = sensor_settings.temperature_settings;
|
let tph_sett = sensor_settings.temperature_settings;
|
||||||
let gas_sett = sensor_settings.gas_settings;
|
let gas_sett = sensor_settings.gas_settings;
|
||||||
|
|
||||||
self.temperature_offset = sensor_settings.temperature_settings.temperature_offset.unwrap_or(0f32);
|
self.temperature_offset = sensor_settings
|
||||||
|
.temperature_settings
|
||||||
|
.temperature_offset
|
||||||
|
.unwrap_or(0f32);
|
||||||
|
|
||||||
let mut reg: [(u8, u8); BME680_REG_BUFFER_LENGTH] = [(0, 0); BME680_REG_BUFFER_LENGTH];
|
let mut reg: [(u8, u8); BME680_REG_BUFFER_LENGTH] = [(0, 0); BME680_REG_BUFFER_LENGTH];
|
||||||
let intended_power_mode = self.power_mode;
|
let intended_power_mode = self.power_mode;
|
||||||
|
@ -459,8 +462,11 @@ impl<I2C: I2c, D: DelayNs> Bme680<I2C, D>
|
||||||
let mut element_index = 0;
|
let mut element_index = 0;
|
||||||
// Selecting the filter
|
// Selecting the filter
|
||||||
if desired_settings.contains(DesiredSensorSettings::FILTER_SIZE_SEL) {
|
if desired_settings.contains(DesiredSensorSettings::FILTER_SIZE_SEL) {
|
||||||
let mut data =
|
let mut data = I2CUtility::read_byte(
|
||||||
I2CUtility::read_byte(&mut self.i2c_bus_handle, self.device_address.addr(), BME680_CONF_ODR_FILT_ADDR)?;
|
&mut self.i2c_bus_handle,
|
||||||
|
self.device_address.addr(),
|
||||||
|
BME680_CONF_ODR_FILT_ADDR,
|
||||||
|
)?;
|
||||||
|
|
||||||
debug!("FILTER_SEL: true");
|
debug!("FILTER_SEL: true");
|
||||||
data = (data as i32 & !0x1ci32
|
data = (data as i32 & !0x1ci32
|
||||||
|
@ -488,8 +494,11 @@ impl<I2C: I2c, D: DelayNs> Bme680<I2C, D>
|
||||||
if desired_settings
|
if desired_settings
|
||||||
.contains(DesiredSensorSettings::OST_SEL | DesiredSensorSettings::OSP_SEL)
|
.contains(DesiredSensorSettings::OST_SEL | DesiredSensorSettings::OSP_SEL)
|
||||||
{
|
{
|
||||||
let mut data =
|
let mut data = I2CUtility::read_byte(
|
||||||
I2CUtility::read_byte(&mut self.i2c_bus_handle, self.device_address.addr(), BME680_CONF_T_P_MODE_ADDR)?;
|
&mut self.i2c_bus_handle,
|
||||||
|
self.device_address.addr(),
|
||||||
|
BME680_CONF_T_P_MODE_ADDR,
|
||||||
|
)?;
|
||||||
|
|
||||||
if desired_settings.contains(DesiredSensorSettings::OST_SEL) {
|
if desired_settings.contains(DesiredSensorSettings::OST_SEL) {
|
||||||
debug!("OST_SEL: true");
|
debug!("OST_SEL: true");
|
||||||
|
@ -504,7 +513,9 @@ impl<I2C: I2c, D: DelayNs> Bme680<I2C, D>
|
||||||
|
|
||||||
if desired_settings.contains(DesiredSensorSettings::OSP_SEL) {
|
if desired_settings.contains(DesiredSensorSettings::OSP_SEL) {
|
||||||
debug!("OSP_SEL: true");
|
debug!("OSP_SEL: true");
|
||||||
let tph_sett_os_pres = tph_sett.temperature_oversampling.unwrap_or(OversamplingSetting::OS1x);
|
let tph_sett_os_pres = tph_sett
|
||||||
|
.temperature_oversampling
|
||||||
|
.unwrap_or(OversamplingSetting::OS1x);
|
||||||
data = (data as i32 & !0x1ci32 | (tph_sett_os_pres as i32) << 2i32 & 0x1ci32) as u8;
|
data = (data as i32 & !0x1ci32 | (tph_sett_os_pres as i32) << 2i32 & 0x1ci32) as u8;
|
||||||
}
|
}
|
||||||
reg[element_index] = (BME680_CONF_T_P_MODE_ADDR, data);
|
reg[element_index] = (BME680_CONF_T_P_MODE_ADDR, data);
|
||||||
|
@ -514,10 +525,17 @@ impl<I2C: I2c, D: DelayNs> Bme680<I2C, D>
|
||||||
// Selecting humidity oversampling for the sensor
|
// Selecting humidity oversampling for the sensor
|
||||||
if desired_settings.contains(DesiredSensorSettings::OSH_SEL) {
|
if desired_settings.contains(DesiredSensorSettings::OSH_SEL) {
|
||||||
debug!("OSH_SEL: true");
|
debug!("OSH_SEL: true");
|
||||||
let tph_sett_os_hum =
|
let tph_sett_os_hum = boundary_check_u8(
|
||||||
boundary_check_u8(tph_sett.humidity_oversampling.map(|x| x as u8), "TphSett.os_hum", 0, 5)?;
|
tph_sett.humidity_oversampling.map(|x| x as u8),
|
||||||
let mut data =
|
"TphSett.os_hum",
|
||||||
I2CUtility::read_byte(&mut self.i2c_bus_handle, self.device_address.addr(), BME680_CONF_OS_H_ADDR)?;
|
0,
|
||||||
|
5,
|
||||||
|
)?;
|
||||||
|
let mut data = I2CUtility::read_byte(
|
||||||
|
&mut self.i2c_bus_handle,
|
||||||
|
self.device_address.addr(),
|
||||||
|
BME680_CONF_OS_H_ADDR,
|
||||||
|
)?;
|
||||||
data = (data as i32 & !0x7i32 | tph_sett_os_hum as i32 & 0x7i32) as u8;
|
data = (data as i32 & !0x7i32 | tph_sett_os_hum as i32 & 0x7i32) as u8;
|
||||||
reg[element_index] = (BME680_CONF_OS_H_ADDR, data);
|
reg[element_index] = (BME680_CONF_OS_H_ADDR, data);
|
||||||
element_index += 1;
|
element_index += 1;
|
||||||
|
@ -571,7 +589,12 @@ impl<I2C: I2c, D: DelayNs> Bme680<I2C, D>
|
||||||
let mut data_array: [u8; BME680_REG_BUFFER_LENGTH] = [0; BME680_REG_BUFFER_LENGTH];
|
let mut data_array: [u8; BME680_REG_BUFFER_LENGTH] = [0; BME680_REG_BUFFER_LENGTH];
|
||||||
let mut sensor_settings: SensorSettings = Default::default();
|
let mut sensor_settings: SensorSettings = Default::default();
|
||||||
|
|
||||||
I2CUtility::read_bytes(&mut self.i2c_bus_handle, self.device_address.addr(), reg_addr, &mut data_array)?;
|
I2CUtility::read_bytes(
|
||||||
|
&mut self.i2c_bus_handle,
|
||||||
|
self.device_address.addr(),
|
||||||
|
reg_addr,
|
||||||
|
&mut data_array,
|
||||||
|
)?;
|
||||||
|
|
||||||
if desired_settings.contains(DesiredSensorSettings::GAS_MEAS_SEL) {
|
if desired_settings.contains(DesiredSensorSettings::GAS_MEAS_SEL) {
|
||||||
sensor_settings.gas_settings = self.get_gas_config()?;
|
sensor_settings.gas_settings = self.get_gas_config()?;
|
||||||
|
@ -588,17 +611,22 @@ impl<I2C: I2c, D: DelayNs> Bme680<I2C, D>
|
||||||
{
|
{
|
||||||
let os_temp: u8 = ((data_array[4usize] as i32 & 0xe0i32) >> 5i32) as u8;
|
let os_temp: u8 = ((data_array[4usize] as i32 & 0xe0i32) >> 5i32) as u8;
|
||||||
let os_pres: u8 = ((data_array[4usize] as i32 & 0x1ci32) >> 2i32) as u8;
|
let os_pres: u8 = ((data_array[4usize] as i32 & 0x1ci32) >> 2i32) as u8;
|
||||||
sensor_settings.temperature_settings.temperature_oversampling = Some(OversamplingSetting::from_u8(os_temp));
|
sensor_settings
|
||||||
sensor_settings.temperature_settings.pressure_oversampling = Some(OversamplingSetting::from_u8(os_pres));
|
.temperature_settings
|
||||||
|
.temperature_oversampling = Some(OversamplingSetting::from_u8(os_temp));
|
||||||
|
sensor_settings.temperature_settings.pressure_oversampling =
|
||||||
|
Some(OversamplingSetting::from_u8(os_pres));
|
||||||
}
|
}
|
||||||
|
|
||||||
if desired_settings.contains(DesiredSensorSettings::OSH_SEL) {
|
if desired_settings.contains(DesiredSensorSettings::OSH_SEL) {
|
||||||
let os_hum: u8 = (data_array[2usize] as i32 & 0x7i32) as u8;
|
let os_hum: u8 = (data_array[2usize] as i32 & 0x7i32) as u8;
|
||||||
sensor_settings.temperature_settings.humidity_oversampling = Some(OversamplingSetting::from_u8(os_hum));
|
sensor_settings.temperature_settings.humidity_oversampling =
|
||||||
|
Some(OversamplingSetting::from_u8(os_hum));
|
||||||
}
|
}
|
||||||
|
|
||||||
if desired_settings.contains(DesiredSensorSettings::HUMIDITY_CONTROL_SEL) {
|
if desired_settings.contains(DesiredSensorSettings::HUMIDITY_CONTROL_SEL) {
|
||||||
sensor_settings.gas_settings.heater_control = Some((data_array[0usize] as i32 & 0x8i32) as u8);
|
sensor_settings.gas_settings.heater_control =
|
||||||
|
Some((data_array[0usize] as i32 & 0x8i32) as u8);
|
||||||
}
|
}
|
||||||
|
|
||||||
if desired_settings
|
if desired_settings
|
||||||
|
@ -627,8 +655,11 @@ impl<I2C: I2c, D: DelayNs> Bme680<I2C, D>
|
||||||
|
|
||||||
// Call repeatedly until in sleep
|
// Call repeatedly until in sleep
|
||||||
loop {
|
loop {
|
||||||
tmp_pow_mode =
|
tmp_pow_mode = I2CUtility::read_byte(
|
||||||
I2CUtility::read_byte(&mut self.i2c_bus_handle, self.device_address.addr(), BME680_CONF_T_P_MODE_ADDR)?;
|
&mut self.i2c_bus_handle,
|
||||||
|
self.device_address.addr(),
|
||||||
|
BME680_CONF_T_P_MODE_ADDR,
|
||||||
|
)?;
|
||||||
|
|
||||||
// Put to sleep before changing mode
|
// Put to sleep before changing mode
|
||||||
current_power_mode = PowerMode::from(tmp_pow_mode & BME680_MODE_MSK);
|
current_power_mode = PowerMode::from(tmp_pow_mode & BME680_MODE_MSK);
|
||||||
|
@ -640,8 +671,7 @@ impl<I2C: I2c, D: DelayNs> Bme680<I2C, D>
|
||||||
tmp_pow_mode &= !BME680_MODE_MSK;
|
tmp_pow_mode &= !BME680_MODE_MSK;
|
||||||
debug!("Setting to sleep tmp_pow_mode: {}", tmp_pow_mode);
|
debug!("Setting to sleep tmp_pow_mode: {}", tmp_pow_mode);
|
||||||
self.bme680_set_registers(&[(BME680_CONF_T_P_MODE_ADDR, tmp_pow_mode)])?;
|
self.bme680_set_registers(&[(BME680_CONF_T_P_MODE_ADDR, tmp_pow_mode)])?;
|
||||||
delay
|
delay.delay_ms(BME680_POLL_PERIOD_MS as u32);
|
||||||
.delay_ms(BME680_POLL_PERIOD_MS as u32);
|
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -657,11 +687,12 @@ impl<I2C: I2c, D: DelayNs> Bme680<I2C, D>
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieve current sensor power mode via registers
|
/// Retrieve current sensor power mode via registers
|
||||||
pub fn get_sensor_mode(
|
pub fn get_sensor_mode(&mut self) -> Result<PowerMode, Bme680Error> {
|
||||||
&mut self,
|
let regs = I2CUtility::read_byte(
|
||||||
) -> Result<PowerMode, Bme680Error> {
|
&mut self.i2c_bus_handle,
|
||||||
let regs =
|
self.device_address.addr(),
|
||||||
I2CUtility::read_byte(&mut self.i2c_bus_handle, self.device_address.addr(), BME680_CONF_T_P_MODE_ADDR)?;
|
BME680_CONF_T_P_MODE_ADDR,
|
||||||
|
)?;
|
||||||
let mode = regs & BME680_MODE_MSK;
|
let mode = regs & BME680_MODE_MSK;
|
||||||
Ok(PowerMode::from(mode))
|
Ok(PowerMode::from(mode))
|
||||||
}
|
}
|
||||||
|
@ -696,17 +727,17 @@ impl<I2C: I2c, D: DelayNs> Bme680<I2C, D>
|
||||||
tph_dur = tph_dur.wrapping_add(1u32);
|
tph_dur = tph_dur.wrapping_add(1u32);
|
||||||
let mut duration = Duration::from_millis(tph_dur as u64);
|
let mut duration = Duration::from_millis(tph_dur as u64);
|
||||||
if sensor_settings.gas_settings.enable_gas_measurement {
|
if sensor_settings.gas_settings.enable_gas_measurement {
|
||||||
duration += sensor_settings.gas_settings.heater_duration.unwrap_or(Duration::default());
|
duration += sensor_settings
|
||||||
|
.gas_settings
|
||||||
|
.heater_duration
|
||||||
|
.unwrap_or(Duration::default());
|
||||||
}
|
}
|
||||||
Ok(duration)
|
Ok(duration)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_calib_data<I2CX>(
|
fn get_calib_data<I2CX>(i2c: &mut I2CX, dev_id: Address) -> Result<CalibrationData, Bme680Error>
|
||||||
i2c: &mut I2CX,
|
where
|
||||||
dev_id: Address,
|
I2CX: I2c,
|
||||||
) -> Result<CalibrationData, Bme680Error>
|
|
||||||
where
|
|
||||||
I2CX: I2c,
|
|
||||||
{
|
{
|
||||||
let mut calib: CalibrationData = Default::default();
|
let mut calib: CalibrationData = Default::default();
|
||||||
|
|
||||||
|
@ -718,7 +749,8 @@ impl<I2C: I2c, D: DelayNs> Bme680<I2C, D>
|
||||||
dev_id.addr(),
|
dev_id.addr(),
|
||||||
BME680_COEFF_ADDR1,
|
BME680_COEFF_ADDR1,
|
||||||
&mut coeff_array[0..(BME680_COEFF_ADDR1_LEN - 1)],
|
&mut coeff_array[0..(BME680_COEFF_ADDR1_LEN - 1)],
|
||||||
).map_err(|_e| { I2CRead })?;
|
)
|
||||||
|
.map_err(|_e| I2CRead)?;
|
||||||
|
|
||||||
I2CUtility::read_bytes::<I2CX>(
|
I2CUtility::read_bytes::<I2CX>(
|
||||||
i2c,
|
i2c,
|
||||||
|
@ -726,7 +758,8 @@ impl<I2C: I2c, D: DelayNs> Bme680<I2C, D>
|
||||||
BME680_COEFF_ADDR2,
|
BME680_COEFF_ADDR2,
|
||||||
&mut coeff_array
|
&mut coeff_array
|
||||||
[BME680_COEFF_ADDR1_LEN..(BME680_COEFF_ADDR1_LEN + BME680_COEFF_ADDR2_LEN - 1)],
|
[BME680_COEFF_ADDR1_LEN..(BME680_COEFF_ADDR1_LEN + BME680_COEFF_ADDR2_LEN - 1)],
|
||||||
).map_err(|_e| { I2CRead })?;
|
)
|
||||||
|
.map_err(|_e| I2CRead)?;
|
||||||
|
|
||||||
calib.par_t1 = ((coeff_array[34usize] as i32) << 8i32 | coeff_array[33usize] as i32) as u16;
|
calib.par_t1 = ((coeff_array[34usize] as i32) << 8i32 | coeff_array[33usize] as i32) as u16;
|
||||||
calib.par_t2 = ((coeff_array[2usize] as i32) << 8i32 | coeff_array[1usize] as i32) as i16;
|
calib.par_t2 = ((coeff_array[2usize] as i32) << 8i32 | coeff_array[1usize] as i32) as i16;
|
||||||
|
@ -757,23 +790,24 @@ impl<I2C: I2c, D: DelayNs> Bme680<I2C, D>
|
||||||
|
|
||||||
calib.res_heat_range =
|
calib.res_heat_range =
|
||||||
(I2CUtility::read_byte::<I2CX>(i2c, dev_id.addr(), BME680_ADDR_RES_HEAT_RANGE_ADDR)
|
(I2CUtility::read_byte::<I2CX>(i2c, dev_id.addr(), BME680_ADDR_RES_HEAT_RANGE_ADDR)
|
||||||
.map_err(|_e| { I2CRead })? & 0x30) / 16;
|
.map_err(|_e| I2CRead)?
|
||||||
|
& 0x30)
|
||||||
|
/ 16;
|
||||||
|
|
||||||
calib.res_heat_val =
|
calib.res_heat_val =
|
||||||
I2CUtility::read_byte::<I2CX>(i2c, dev_id.addr(), BME680_ADDR_RES_HEAT_VAL_ADDR)
|
I2CUtility::read_byte::<I2CX>(i2c, dev_id.addr(), BME680_ADDR_RES_HEAT_VAL_ADDR)
|
||||||
.map_err(|_e| { I2CRead })? as i8;
|
.map_err(|_e| I2CRead)? as i8;
|
||||||
|
|
||||||
calib.range_sw_err =
|
calib.range_sw_err =
|
||||||
(I2CUtility::read_byte::<I2CX>(i2c, dev_id.addr(), BME680_ADDR_RANGE_SW_ERR_ADDR)
|
(I2CUtility::read_byte::<I2CX>(i2c, dev_id.addr(), BME680_ADDR_RANGE_SW_ERR_ADDR)
|
||||||
.map_err(|_e| { I2CRead })? & BME680_RSERROR_MSK) / 16;
|
.map_err(|_e| I2CRead)?
|
||||||
|
& BME680_RSERROR_MSK)
|
||||||
|
/ 16;
|
||||||
|
|
||||||
Ok(calib)
|
Ok(calib)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_gas_config(
|
fn set_gas_config(&mut self, gas_sett: GasSettings) -> Result<(), Bme680Error> {
|
||||||
&mut self,
|
|
||||||
gas_sett: GasSettings,
|
|
||||||
) -> Result<(), Bme680Error> {
|
|
||||||
if self.power_mode != PowerMode::ForcedMode {
|
if self.power_mode != PowerMode::ForcedMode {
|
||||||
return Err(Bme680Error::DefinePwrMode);
|
return Err(Bme680Error::DefinePwrMode);
|
||||||
}
|
}
|
||||||
|
@ -789,7 +823,11 @@ impl<I2C: I2c, D: DelayNs> Bme680<I2C, D>
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
BME680_GAS_WAIT0_ADDR,
|
BME680_GAS_WAIT0_ADDR,
|
||||||
Calculation::heater_duration(gas_sett.heater_duration.unwrap_or_else(|| Duration::from_secs(0))),
|
Calculation::heater_duration(
|
||||||
|
gas_sett
|
||||||
|
.heater_duration
|
||||||
|
.unwrap_or_else(|| Duration::from_secs(0)),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -858,8 +896,11 @@ impl<I2C: I2c, D: DelayNs> Bme680<I2C, D>
|
||||||
data.status |= buff[14] & BME680_HEAT_STAB_MSK;
|
data.status |= buff[14] & BME680_HEAT_STAB_MSK;
|
||||||
|
|
||||||
if data.status & BME680_NEW_DATA_MSK != 0 {
|
if data.status & BME680_NEW_DATA_MSK != 0 {
|
||||||
let (temp, t_fine) =
|
let (temp, t_fine) = Calculation::temperature(
|
||||||
Calculation::temperature(&self.calibration_data, adc_temp, Some(self.temperature_offset));
|
&self.calibration_data,
|
||||||
|
adc_temp,
|
||||||
|
Some(self.temperature_offset),
|
||||||
|
);
|
||||||
debug!(
|
debug!(
|
||||||
"adc_temp: {} adc_pres: {} adc_hum: {} adc_gas_res: {}, t_fine: {}",
|
"adc_temp: {} adc_pres: {} adc_hum: {} adc_gas_res: {}, t_fine: {}",
|
||||||
adc_temp, adc_pres, adc_hum, adc_gas_res, t_fine
|
adc_temp, adc_pres, adc_hum, adc_gas_res, t_fine
|
||||||
|
|
|
@ -195,21 +195,33 @@ impl SettingsBuilder {
|
||||||
mut self,
|
mut self,
|
||||||
temperature_oversampling: OversamplingSetting,
|
temperature_oversampling: OversamplingSetting,
|
||||||
) -> SettingsBuilder {
|
) -> SettingsBuilder {
|
||||||
self.sensor_settings.temperature_settings.temperature_oversampling = Some(temperature_oversampling);
|
self.sensor_settings
|
||||||
|
.temperature_settings
|
||||||
|
.temperature_oversampling = Some(temperature_oversampling);
|
||||||
self.desired_settings |= DesiredSensorSettings::OST_SEL;
|
self.desired_settings |= DesiredSensorSettings::OST_SEL;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// With pressure oversampling.
|
/// With pressure oversampling.
|
||||||
pub fn with_pressure_oversampling(mut self, pressure_oversampling: OversamplingSetting) -> SettingsBuilder {
|
pub fn with_pressure_oversampling(
|
||||||
self.sensor_settings.temperature_settings.pressure_oversampling = Some(pressure_oversampling);
|
mut self,
|
||||||
|
pressure_oversampling: OversamplingSetting,
|
||||||
|
) -> SettingsBuilder {
|
||||||
|
self.sensor_settings
|
||||||
|
.temperature_settings
|
||||||
|
.pressure_oversampling = Some(pressure_oversampling);
|
||||||
self.desired_settings |= DesiredSensorSettings::OSP_SEL;
|
self.desired_settings |= DesiredSensorSettings::OSP_SEL;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// With humidity oversampling.
|
/// With humidity oversampling.
|
||||||
pub fn with_humidity_oversampling(mut self, humidity_oversampling: OversamplingSetting) -> SettingsBuilder {
|
pub fn with_humidity_oversampling(
|
||||||
self.sensor_settings.temperature_settings.humidity_oversampling = Some(humidity_oversampling);
|
mut self,
|
||||||
|
humidity_oversampling: OversamplingSetting,
|
||||||
|
) -> SettingsBuilder {
|
||||||
|
self.sensor_settings
|
||||||
|
.temperature_settings
|
||||||
|
.humidity_oversampling = Some(humidity_oversampling);
|
||||||
self.desired_settings |= DesiredSensorSettings::OSH_SEL;
|
self.desired_settings |= DesiredSensorSettings::OSH_SEL;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue