Close, down to 15 build errors
This commit is contained in:
parent
ee146c6fc3
commit
cc3a5ca508
3 changed files with 360 additions and 293 deletions
638
src/bme680.rs
638
src/bme680.rs
|
@ -1,6 +1,9 @@
|
||||||
use byteorder::{BigEndian, LittleEndian, ReadBytesExt, WriteBytesExt};
|
use byteorder::{BigEndian, LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||||
|
|
||||||
use hal::blocking::delay::DelayMs;
|
use hal::blocking::delay::DelayMs;
|
||||||
|
use hal::blocking::i2c::{Read, Write, WriteRead};
|
||||||
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
use std::result;
|
use std::result;
|
||||||
|
|
||||||
/** BME680 General config */
|
/** BME680 General config */
|
||||||
|
@ -14,7 +17,7 @@ pub const BME680_I2C_ADDR_SECONDARY: u8 = 0x77;
|
||||||
pub const BME680_CHIP_ID: u8 = 0x61;
|
pub const BME680_CHIP_ID: u8 = 0x61;
|
||||||
|
|
||||||
/** BME680 coefficients related defines */
|
/** BME680 coefficients related defines */
|
||||||
pub const BME680_COEFF_SIZE: u8 = 41;
|
pub const BME680_COEFF_SIZE: usize = 41;
|
||||||
pub const BME680_COEFF_ADDR1_LEN: u8 = 25;
|
pub const BME680_COEFF_ADDR1_LEN: u8 = 25;
|
||||||
pub const BME680_COEFF_ADDR2_LEN: u8 = 16;
|
pub const BME680_COEFF_ADDR2_LEN: u8 = 16;
|
||||||
|
|
||||||
|
@ -32,6 +35,14 @@ pub const BME680_E_COM_FAIL: i8 = -2;
|
||||||
pub const BME680_E_DEV_NOT_FOUND: i8 = -3;
|
pub const BME680_E_DEV_NOT_FOUND: i8 = -3;
|
||||||
pub const BME680_E_INVALID_LENGTH: i8 = -4;
|
pub const BME680_E_INVALID_LENGTH: i8 = -4;
|
||||||
|
|
||||||
|
/** Register map */
|
||||||
|
/** Other coefficient's address */
|
||||||
|
pub const BME680_ADDR_RES_HEAT_VAL_ADDR: u8 = 0x00;
|
||||||
|
pub const BME680_ADDR_RES_HEAT_RANGE_ADDR: u8 = 0x02;
|
||||||
|
pub const BME680_ADDR_RANGE_SW_ERR_ADDR: u8 = 0x04;
|
||||||
|
pub const BME680_ADDR_SENS_CONF_START: u8 = 0x5A;
|
||||||
|
pub const BME680_ADDR_GAS_CONF_START: u8 = 0x64;
|
||||||
|
|
||||||
pub const BME680_SOFT_RESET_ADDR: u8 = 0xe0;
|
pub const BME680_SOFT_RESET_ADDR: u8 = 0xe0;
|
||||||
|
|
||||||
/** Field settings */
|
/** Field settings */
|
||||||
|
@ -59,7 +70,7 @@ pub const BME680_CHIP_ID_ADDR: u8 = 0xd0;
|
||||||
pub const BME680_SLEEP_MODE: u8 = 0;
|
pub const BME680_SLEEP_MODE: u8 = 0;
|
||||||
pub const BME680_FORCED_MODE: u8 = 1;
|
pub const BME680_FORCED_MODE: u8 = 1;
|
||||||
|
|
||||||
pub const BME680_RESET_PERIOD: u32 = 10;
|
pub const BME680_RESET_PERIOD: u8 = 10;
|
||||||
|
|
||||||
pub const BME680_GAS_MEAS_MSK: u8 = 0x30;
|
pub const BME680_GAS_MEAS_MSK: u8 = 0x30;
|
||||||
pub const BME680_NBCONV_MSK: u8 = 0x0F;
|
pub const BME680_NBCONV_MSK: u8 = 0x0F;
|
||||||
|
@ -98,6 +109,17 @@ pub const BME680_REG_BUFFER_LENGTH: u8 = 6;
|
||||||
pub const BME680_FIELD_DATA_LENGTH: u8 = 3;
|
pub const BME680_FIELD_DATA_LENGTH: u8 = 3;
|
||||||
pub const BME680_GAS_REG_BUF_LENGTH: u8 = 20;
|
pub const BME680_GAS_REG_BUF_LENGTH: u8 = 20;
|
||||||
|
|
||||||
|
/* Settings selector */
|
||||||
|
pub const BME680_OST_SEL: u16 = 1;
|
||||||
|
pub const BME680_OSP_SEL: u16 = 2;
|
||||||
|
pub const BME680_OSH_SEL: u16 = 4;
|
||||||
|
pub const BME680_GAS_MEAS_SEL: u16 = 8;
|
||||||
|
pub const BME680_FILTER_SEL: u16 = 16;
|
||||||
|
pub const BME680_HCNTRL_SEL: u16 = 32;
|
||||||
|
pub const BME680_RUN_GAS_SEL: u16 = 64;
|
||||||
|
pub const BME680_NBCONV_SEL: u16 = 128;
|
||||||
|
pub const BME680_GAS_SENSOR_SEL: u16 = BME680_GAS_MEAS_SEL | BME680_RUN_GAS_SEL | BME680_NBCONV_SEL;
|
||||||
|
|
||||||
pub enum Bme680Error {
|
pub enum Bme680Error {
|
||||||
///
|
///
|
||||||
/// aka BME680_E_NULL_PTR
|
/// aka BME680_E_NULL_PTR
|
||||||
|
@ -123,6 +145,10 @@ pub enum Bme680Error {
|
||||||
/// Warning aka BME680_W_DEFINE_PWR_MODE
|
/// Warning aka BME680_W_DEFINE_PWR_MODE
|
||||||
///
|
///
|
||||||
NoNewData,
|
NoNewData,
|
||||||
|
///
|
||||||
|
/// Warning Boundary Check
|
||||||
|
///
|
||||||
|
BoundaryCheckFailure(InfoMsg, u8, u8),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Result<T> = result::Result<T, Bme680Error>;
|
pub type Result<T> = result::Result<T, Bme680Error>;
|
||||||
|
@ -130,7 +156,7 @@ pub type Result<T> = result::Result<T, Bme680Error>;
|
||||||
///
|
///
|
||||||
/// Power mode settings
|
/// Power mode settings
|
||||||
///
|
///
|
||||||
#[derive(Clone, Copy)]
|
#[derive(PartialEq, Clone, Copy)]
|
||||||
pub enum PowerMode {
|
pub enum PowerMode {
|
||||||
SleepMode,
|
SleepMode,
|
||||||
ForcedMode,
|
ForcedMode,
|
||||||
|
@ -160,9 +186,9 @@ pub enum Bme680_intf {
|
||||||
BME680_I2C_INTF,
|
BME680_I2C_INTF,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy)]
|
#[derive(Default, Copy)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct Bme680_calib_data {
|
pub struct CalibData {
|
||||||
pub par_h1: u16,
|
pub par_h1: u16,
|
||||||
pub par_h2: u16,
|
pub par_h2: u16,
|
||||||
pub par_h3: i8,
|
pub par_h3: i8,
|
||||||
|
@ -192,7 +218,7 @@ pub struct Bme680_calib_data {
|
||||||
pub range_sw_err: i8,
|
pub range_sw_err: i8,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clone for Bme680_calib_data {
|
impl Clone for CalibData {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
*self
|
*self
|
||||||
}
|
}
|
||||||
|
@ -200,14 +226,14 @@ impl Clone for Bme680_calib_data {
|
||||||
|
|
||||||
#[derive(Copy)]
|
#[derive(Copy)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct Bme680_tph_sett {
|
pub struct TphSett {
|
||||||
pub os_hum: u8,
|
pub os_hum: u8,
|
||||||
pub os_temp: u8,
|
pub os_temp: u8,
|
||||||
pub os_pres: u8,
|
pub os_pres: u8,
|
||||||
pub filter: u8,
|
pub filter: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clone for Bme680_tph_sett {
|
impl Clone for TphSett {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
*self
|
*self
|
||||||
}
|
}
|
||||||
|
@ -215,7 +241,7 @@ impl Clone for Bme680_tph_sett {
|
||||||
|
|
||||||
#[derive(Default, Copy)]
|
#[derive(Default, Copy)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct Bme680_gas_sett {
|
pub struct GasSett {
|
||||||
pub nb_conv: u8,
|
pub nb_conv: u8,
|
||||||
pub heatr_ctrl: u8,
|
pub heatr_ctrl: u8,
|
||||||
pub run_gas: u8,
|
pub run_gas: u8,
|
||||||
|
@ -223,7 +249,7 @@ pub struct Bme680_gas_sett {
|
||||||
pub heatr_dur: u16,
|
pub heatr_dur: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clone for Bme680_gas_sett {
|
impl Clone for GasSett {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
*self
|
*self
|
||||||
}
|
}
|
||||||
|
@ -231,7 +257,7 @@ impl Clone for Bme680_gas_sett {
|
||||||
|
|
||||||
#[derive(Default, Copy)]
|
#[derive(Default, Copy)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct Bme680_field_data {
|
pub struct FieldData {
|
||||||
pub status: u8,
|
pub status: u8,
|
||||||
pub gas_index: u8,
|
pub gas_index: u8,
|
||||||
pub meas_index: u8,
|
pub meas_index: u8,
|
||||||
|
@ -241,12 +267,60 @@ pub struct Bme680_field_data {
|
||||||
pub gas_resistance: u32,
|
pub gas_resistance: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clone for Bme680_field_data {
|
impl Clone for FieldData {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
*self
|
*self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// TODO - replace naming of "State" with something better
|
||||||
|
/// aka new_fields - BME680_NEW_DATA_MSK
|
||||||
|
///
|
||||||
|
pub enum FieldDataState {
|
||||||
|
NewData,
|
||||||
|
// TODO find better naming to no new data
|
||||||
|
NoNewData,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Infos
|
||||||
|
bitflags! {
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct InfoMsg: u8 {
|
||||||
|
const MIN_CORRECTION = 1;
|
||||||
|
const MAX_CORRECTION = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct SensorSettings {
|
||||||
|
gas_sett: Option<GasSett>,
|
||||||
|
tph_sett: Option<TphSett>,
|
||||||
|
}
|
||||||
|
|
||||||
|
bitflags! {
|
||||||
|
pub struct DesiredSensorSettings: u16 {
|
||||||
|
/// To set temperature oversampling
|
||||||
|
const OST_SEL = 1;
|
||||||
|
/// To set pressure oversampling.
|
||||||
|
const OSP_SEL = 2;
|
||||||
|
|
||||||
|
/// To set humidity oversampling.
|
||||||
|
const OSH_SEL = 4;
|
||||||
|
/// To set gas measurement setting.
|
||||||
|
const GAS_MEAS_SEL = 8;
|
||||||
|
/// To set filter setting.
|
||||||
|
const FILTER_SEL = 16;
|
||||||
|
/// To set humidity control setting.
|
||||||
|
const HCNTRL_SEL = 32;
|
||||||
|
/// To set run gas setting.
|
||||||
|
const RUN_GAS_SEL = 64;
|
||||||
|
/// To set NB conversion setting.
|
||||||
|
const NBCONV_SEL = 128;
|
||||||
|
/// To set all gas sensor related settings
|
||||||
|
const GAS_SENSOR_SEL = Self::GAS_MEAS_SEL.bits | Self::RUN_GAS_SEL.bits | Self::NBCONV_SEL.bits;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Copy)]
|
#[derive(Copy)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct Bme680_dev<I2C, D> {
|
pub struct Bme680_dev<I2C, D> {
|
||||||
|
@ -255,13 +329,12 @@ pub struct Bme680_dev<I2C, D> {
|
||||||
pub dev_id: u8,
|
pub dev_id: u8,
|
||||||
pub mem_page: u8,
|
pub mem_page: u8,
|
||||||
pub amb_temp: i8,
|
pub amb_temp: i8,
|
||||||
pub calib: Bme680_calib_data,
|
pub calib: CalibData,
|
||||||
pub tph_sett: Bme680_tph_sett,
|
pub tph_sett: TphSett,
|
||||||
pub gas_sett: Bme680_gas_sett,
|
pub gas_sett: GasSett,
|
||||||
pub power_mode: PowerMode,
|
pub power_mode: PowerMode,
|
||||||
pub new_fields: u8,
|
pub new_fields: u8,
|
||||||
pub info_msg: u8,
|
pub info_msg: u8,
|
||||||
pub com_rslt: i8,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I2C, D> Clone for Bme680_dev<I2C, D> {
|
impl<I2C, D> Clone for Bme680_dev<I2C, D> {
|
||||||
|
@ -273,14 +346,15 @@ impl<I2C, D> Clone for Bme680_dev<I2C, D> {
|
||||||
impl<I2C, D> Bme680_dev<I2C, D>
|
impl<I2C, D> Bme680_dev<I2C, D>
|
||||||
where
|
where
|
||||||
D: DelayMs<u8>,
|
D: DelayMs<u8>,
|
||||||
|
I2C: Read + Write,
|
||||||
{
|
{
|
||||||
pub fn init(self) -> Result<Bme680_calib_data> {
|
pub fn init(self) -> Result<CalibData> {
|
||||||
self.soft_reset()?;
|
self.soft_reset()?;
|
||||||
|
|
||||||
/* Soft reset to restore it to default values*/
|
/* Soft reset to restore it to default values*/
|
||||||
let chip_id = self.get_regs_u8(BME680_CHIP_ID_ADDR)?;
|
let chip_id = self.get_regs_u8(BME680_CHIP_ID_ADDR)?;
|
||||||
if chip_id == BME680_CHIP_ID {
|
if chip_id == BME680_CHIP_ID {
|
||||||
self.calib = self.get_calib_data();
|
self.calib = self.get_calib_data()?;
|
||||||
Ok(self.calib)
|
Ok(self.calib)
|
||||||
} else {
|
} else {
|
||||||
Err(Bme680Error::DeviceNotFound)
|
Err(Bme680Error::DeviceNotFound)
|
||||||
|
@ -289,7 +363,7 @@ where
|
||||||
|
|
||||||
pub fn get_regs_u8(self, reg_addr: u8) -> Result<u8> {
|
pub fn get_regs_u8(self, reg_addr: u8) -> Result<u8> {
|
||||||
let mut buf = [0; 1];
|
let mut buf = [0; 1];
|
||||||
match self.i2c.read(reg_addr, buf) {
|
match self.i2c.read(reg_addr, &mut buf) {
|
||||||
Ok(()) => Ok(buf[0]),
|
Ok(()) => Ok(buf[0]),
|
||||||
Err(_) => Err(Bme680Error::CommunicationFailure),
|
Err(_) => Err(Bme680Error::CommunicationFailure),
|
||||||
}
|
}
|
||||||
|
@ -297,25 +371,20 @@ where
|
||||||
|
|
||||||
pub fn get_regs_i8(self, reg_addr: u8) -> Result<i8> {
|
pub fn get_regs_i8(self, reg_addr: u8) -> Result<i8> {
|
||||||
let mut buf = [0; 1];
|
let mut buf = [0; 1];
|
||||||
match self.i2c.read(reg_addr, buf) {
|
match self.i2c.read(reg_addr, &mut buf) {
|
||||||
Ok(()) => Ok(buf[0]),
|
Ok(()) => Ok(i8::try_from(buf[0]).expect("U8 overflow when reading register")),
|
||||||
Err(_) => Err(Bme680Error::CommunicationFailure),
|
Err(_) => Err(Bme680Error::CommunicationFailure),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bme680_set_regs(
|
pub fn bme680_set_regs(self, reg_addr: u8, reg_data: *const u8, len: u8) -> Result<()> {
|
||||||
self,
|
|
||||||
mut reg_addr: *const u8,
|
|
||||||
mut reg_data: *const u8,
|
|
||||||
mut len: u8,
|
|
||||||
) -> Result<()> {
|
|
||||||
let mut tmp_buff = [0, BME680_TMP_BUFFER_LENGTH];
|
let mut tmp_buff = [0, BME680_TMP_BUFFER_LENGTH];
|
||||||
|
|
||||||
let mut index: u16;
|
let mut index: u16;
|
||||||
if len > 0 && (len < BME680_TMP_BUFFER_LENGTH / 2) {
|
if len > 0 && (len < BME680_TMP_BUFFER_LENGTH / 2) {
|
||||||
index = 0;
|
index = 0;
|
||||||
loop {
|
loop {
|
||||||
if !(index < len) {
|
if !(index < len as u16) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tmp_buff[(2 * index) as (usize)] = *reg_addr.offset(index as (isize));
|
tmp_buff[(2 * index) as (usize)] = *reg_addr.offset(index as (isize));
|
||||||
|
@ -323,21 +392,9 @@ where
|
||||||
index = index + 1;
|
index = index + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if rslt as (i32) == BME680_OK {
|
|
||||||
self.i2c
|
self.i2c
|
||||||
.write(reg_addr, tmp_buff)
|
.write(reg_addr, &tmp_buff)
|
||||||
.map_err(Bme680Error::CommunicationFailure);
|
.map_err(|_| Bme680Error::CommunicationFailure)
|
||||||
//self.com_rslt = self.i2c.write(
|
|
||||||
// self.dev_id,
|
|
||||||
// tmp_buff[0usize],
|
|
||||||
// &mut tmp_buff[1usize] as (*mut u8),
|
|
||||||
// (2 * len - 1),
|
|
||||||
//);
|
|
||||||
|
|
||||||
if self.com_rslt != 0 {
|
|
||||||
Err(Bme680Error::CommunicationFailure)
|
|
||||||
}
|
|
||||||
//}
|
|
||||||
} else {
|
} else {
|
||||||
Err(Bme680Error::InvalidLength)
|
Err(Bme680Error::InvalidLength)
|
||||||
}
|
}
|
||||||
|
@ -349,28 +406,30 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bme680_set_sensor_settings(self, mut desired_settings: u16) -> i8 {
|
// TODO replace parameter desired_settings with safe flags
|
||||||
let mut rslt: i8;
|
pub fn bme680_set_sensor_settings(
|
||||||
|
self,
|
||||||
|
desired_settings: DesiredSensorSettings,
|
||||||
|
gas_sett: Option<GasSett>,
|
||||||
|
) -> Result<()> {
|
||||||
let mut reg_addr: u8;
|
let mut reg_addr: u8;
|
||||||
let mut data: u8 = 0u8;
|
// let mut data: u8 = 0u8;
|
||||||
let mut count: u8 = 0u8;
|
let mut count: u8 = 0u8;
|
||||||
let mut reg_array: [u8; 6] = 0i32 as ([u8; 6]);
|
let mut reg_array: [u8; 6] = 0i32 as ([u8; 6]);
|
||||||
let mut data_array: [u8; 6] = 0i32 as ([u8; 6]);
|
let mut data_array: [u8; 6] = 0i32 as ([u8; 6]);
|
||||||
let mut intended_power_mode: u8 = self.power_mode;
|
let mut intended_power_mode = self.power_mode;
|
||||||
if desired_settings as (i32) & 8i32 != 0 {
|
|
||||||
rslt = self.set_gas_config();
|
if desired_settings.contains(DesiredSensorSettings::GAS_MEAS_SEL) {
|
||||||
|
self.set_gas_config(gas_sett.unwrap())?;
|
||||||
}
|
}
|
||||||
self.power_mode = 0u8;
|
|
||||||
if rslt as (i32) == BME680_OK {
|
self.bme680_set_sensor_mode(self.power_mode)?;
|
||||||
rslt = self.bme680_set_sensor_mode();
|
|
||||||
}
|
if desired_settings.contains(DesiredSensorSettings::FILTER_SEL) {
|
||||||
if desired_settings as (i32) & 16i32 != 0 {
|
self.boundary_check(self.tph_sett.filter, 0, 7)?;
|
||||||
rslt = self.boundary_check(&mut self.tph_sett.filter as (*mut u8), 0u8, 7u8);
|
|
||||||
reg_addr = 0x75u8;
|
reg_addr = 0x75u8;
|
||||||
if rslt as (i32) == BME680_OK {
|
let mut data = self.get_regs_u8(reg_addr)?;
|
||||||
rslt = self.get_regs(reg_addr, &mut data as (*mut u8), 1u16);
|
if desired_settings.contains(DesiredSensorSettings::FILTER_SEL) {
|
||||||
}
|
|
||||||
if desired_settings as (i32) & 16i32 != 0 {
|
|
||||||
data = (data as (i32) & !0x1ci32 | self.tph_sett.filter as (i32) << 2i32 & 0x1ci32)
|
data = (data as (i32) & !0x1ci32 | self.tph_sett.filter as (i32) << 2i32 & 0x1ci32)
|
||||||
as (u8);
|
as (u8);
|
||||||
}
|
}
|
||||||
|
@ -378,165 +437,170 @@ where
|
||||||
data_array[count as (usize)] = data;
|
data_array[count as (usize)] = data;
|
||||||
count = (count as (i32) + 1) as (u8);
|
count = (count as (i32) + 1) as (u8);
|
||||||
}
|
}
|
||||||
if desired_settings as (i32) & 32i32 != 0 {
|
|
||||||
rslt = self.boundary_check(&mut self.gas_sett.heatr_ctrl as (*mut u8), 0x0u8, 0x8u8);
|
if desired_settings.contains(DesiredSensorSettings::HCNTRL_SEL) {
|
||||||
|
self.boundary_check(self.gas_sett.heatr_ctrl, 0x0u8, 0x8u8)?;
|
||||||
reg_addr = 0x70u8;
|
reg_addr = 0x70u8;
|
||||||
if rslt as (i32) == BME680_OK {
|
let mut data = self.get_regs_u8(reg_addr)?;
|
||||||
rslt = self.get_regs(reg_addr, &mut data as (*mut u8), 1u16);
|
|
||||||
}
|
|
||||||
data = (data as (i32) & !0x8i32 | self.gas_sett.heatr_ctrl as (i32) & 0x8i32) as (u8);
|
data = (data as (i32) & !0x8i32 | self.gas_sett.heatr_ctrl as (i32) & 0x8i32) as (u8);
|
||||||
reg_array[count as (usize)] = reg_addr;
|
reg_array[count as (usize)] = reg_addr;
|
||||||
data_array[count as (usize)] = data;
|
data_array[count as (usize)] = data;
|
||||||
count = (count as (i32) + 1) as (u8);
|
count = (count as (i32) + 1) as (u8);
|
||||||
}
|
}
|
||||||
if desired_settings as (i32) & (1i32 | 2i32) != 0 {
|
|
||||||
rslt = self.boundary_check(&mut self.tph_sett.os_temp as (*mut u8), 0u8, 5u8);
|
if desired_settings
|
||||||
|
.contains(DesiredSensorSettings::OST_SEL | DesiredSensorSettings::OSP_SEL)
|
||||||
|
{
|
||||||
|
self.boundary_check(self.tph_sett.os_temp, 0, 5)?;
|
||||||
reg_addr = 0x74u8;
|
reg_addr = 0x74u8;
|
||||||
if rslt as (i32) == BME680_OK {
|
let mut data = self.get_regs_u8(reg_addr)?;
|
||||||
rslt = self.get_regs(reg_addr, &mut data as (*mut u8), 1u16);
|
|
||||||
}
|
if desired_settings.contains(DesiredSensorSettings::OST_SEL) {
|
||||||
if desired_settings as (i32) & 1i32 != 0 {
|
|
||||||
data = (data as (i32) & !0xe0i32 | self.tph_sett.os_temp as (i32) << 5i32 & 0xe0i32)
|
data = (data as (i32) & !0xe0i32 | self.tph_sett.os_temp as (i32) << 5i32 & 0xe0i32)
|
||||||
as (u8);
|
as (u8);
|
||||||
}
|
}
|
||||||
if desired_settings as (i32) & 2i32 != 0 {
|
|
||||||
|
if desired_settings.contains(DesiredSensorSettings::OSP_SEL) {
|
||||||
data = (data as (i32) & !0x1ci32 | self.tph_sett.os_pres as (i32) << 2i32 & 0x1ci32)
|
data = (data as (i32) & !0x1ci32 | self.tph_sett.os_pres as (i32) << 2i32 & 0x1ci32)
|
||||||
as (u8);
|
as (u8);
|
||||||
}
|
}
|
||||||
|
|
||||||
reg_array[count as (usize)] = reg_addr;
|
reg_array[count as (usize)] = reg_addr;
|
||||||
data_array[count as (usize)] = data;
|
data_array[count as (usize)] = data;
|
||||||
count = (count as (i32) + 1) as (u8);
|
count = (count as (i32) + 1) as (u8);
|
||||||
}
|
}
|
||||||
if desired_settings as (i32) & 4i32 != 0 {
|
|
||||||
rslt = self.boundary_check(&mut self.tph_sett.os_hum as (*mut u8), 0u8, 5u8);
|
if desired_settings.contains(DesiredSensorSettings::OSH_SEL) {
|
||||||
|
self.boundary_check(self.tph_sett.os_hum, 0, 5)?;
|
||||||
reg_addr = 0x72u8;
|
reg_addr = 0x72u8;
|
||||||
if rslt as (i32) == BME680_OK {
|
let mut data = self.get_regs_u8(reg_addr)?;
|
||||||
rslt = self.get_regs(reg_addr, &mut data as (*mut u8), 1u16);
|
|
||||||
}
|
|
||||||
data = (data as (i32) & !0x7i32 | self.tph_sett.os_hum as (i32) & 0x7i32) as (u8);
|
data = (data as (i32) & !0x7i32 | self.tph_sett.os_hum as (i32) & 0x7i32) as (u8);
|
||||||
reg_array[count as (usize)] = reg_addr;
|
reg_array[count as (usize)] = reg_addr;
|
||||||
data_array[count as (usize)] = data;
|
data_array[count as (usize)] = data;
|
||||||
count = (count as (i32) + 1) as (u8);
|
count = (count as (i32) + 1) as (u8);
|
||||||
}
|
}
|
||||||
if desired_settings as (i32) & (64i32 | 128i32) != 0 {
|
|
||||||
rslt = self.boundary_check(&mut self.gas_sett.run_gas as (*mut u8), 0u8, 1u8);
|
if desired_settings
|
||||||
if rslt as (i32) == BME680_OK {
|
.contains(DesiredSensorSettings::RUN_GAS_SEL | DesiredSensorSettings::NBCONV_SEL)
|
||||||
rslt = self.boundary_check(&mut self.gas_sett.nb_conv as (*mut u8), 0u8, 10u8);
|
{
|
||||||
}
|
self.boundary_check(self.gas_sett.run_gas, 0, 1)?;
|
||||||
|
self.boundary_check(self.gas_sett.nb_conv, 0, 10)?;
|
||||||
reg_addr = 0x71u8;
|
reg_addr = 0x71u8;
|
||||||
if rslt as (i32) == BME680_OK {
|
let mut data = self.get_regs_u8(reg_addr)?;
|
||||||
rslt = self.get_regsy(reg_addr, &mut data as (*mut u8), 1u16);
|
|
||||||
}
|
if desired_settings.contains(DesiredSensorSettings::RUN_GAS_SEL) {
|
||||||
if desired_settings as (i32) & 64i32 != 0 {
|
|
||||||
data = (data as (i32) & !0x10i32 | self.gas_sett.run_gas as (i32) << 4i32 & 0x10i32)
|
data = (data as (i32) & !0x10i32 | self.gas_sett.run_gas as (i32) << 4i32 & 0x10i32)
|
||||||
as (u8);
|
as (u8);
|
||||||
}
|
}
|
||||||
if desired_settings as (i32) & 128i32 != 0 {
|
|
||||||
|
if desired_settings.contains(DesiredSensorSettings::NBCONV_SEL) {
|
||||||
data = (data as (i32) & !0xfi32 | self.gas_sett.nb_conv as (i32) & 0xfi32) as (u8);
|
data = (data as (i32) & !0xfi32 | self.gas_sett.nb_conv as (i32) & 0xfi32) as (u8);
|
||||||
}
|
}
|
||||||
|
|
||||||
reg_array[count as (usize)] = reg_addr;
|
reg_array[count as (usize)] = reg_addr;
|
||||||
data_array[count as (usize)] = data;
|
data_array[count as (usize)] = data;
|
||||||
count = (count as (i32) + 1) as (u8);
|
count = (count as (i32) + 1) as (u8);
|
||||||
}
|
}
|
||||||
if rslt as (i32) == BME680_OK {
|
|
||||||
rslt = self.bme680_set_regs(
|
self.bme680_set_regs(
|
||||||
reg_array.as_mut_ptr() as (*const u8),
|
reg_array.as_mut_ptr() as (*const u8),
|
||||||
data_array.as_mut_ptr() as (*const u8),
|
data_array.as_mut_ptr() as (*const u8),
|
||||||
count,
|
count,
|
||||||
);
|
)?;
|
||||||
}
|
|
||||||
self.power_mode = intended_power_mode;
|
self.power_mode = intended_power_mode;
|
||||||
rslt
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_sensor_settings(self, mut desired_settings: u16) -> i8 {
|
// TODO replace desired_settings with proper flags type see lib.rs
|
||||||
let mut rslt: i8;
|
pub fn get_sensor_settings(self, mut desired_settings: u16) -> Result<SensorSettings> {
|
||||||
let mut reg_addr: u8 = 0x70u8;
|
let mut reg_addr: u8 = 0x70u8;
|
||||||
let mut data_array: [u8; 6] = 0i32 as ([u8; 6]);
|
let mut data_array: [u8; 6] = 0i32 as ([u8; 6]);
|
||||||
rslt = self.get_regs(reg_addr, data_array.as_mut_ptr(), 6u16);
|
let mut sensor_settings = Default::default();
|
||||||
if rslt as (i32) == BME680_OK {
|
|
||||||
if desired_settings as (i32) & 8i32 != 0 {
|
let data_array = self.get_regs(reg_addr, data_array.as_mut_ptr(), 6u16)?;
|
||||||
rslt = self.get_gas_config();
|
|
||||||
}
|
if desired_settings as (i32) & 8i32 != 0 {
|
||||||
if desired_settings as (i32) & 16i32 != 0 {
|
sensor_settings.gas_sett = Some(self.get_gas_config()?);
|
||||||
self.tph_sett.filter = ((data_array[5usize] as (i32) & 0x1ci32) >> 2i32) as (u8);
|
|
||||||
}
|
|
||||||
if desired_settings as (i32) & (1i32 | 2i32) != 0 {
|
|
||||||
self.tph_sett.os_temp = ((data_array[4usize] as (i32) & 0xe0i32) >> 5i32) as (u8);
|
|
||||||
self.tph_sett.os_pres = ((data_array[4usize] as (i32) & 0x1ci32) >> 2i32) as (u8);
|
|
||||||
}
|
|
||||||
if desired_settings as (i32) & 4i32 != 0 {
|
|
||||||
self.tph_sett.os_hum = (data_array[2usize] as (i32) & 0x7i32) as (u8);
|
|
||||||
}
|
|
||||||
if desired_settings as (i32) & 32i32 != 0 {
|
|
||||||
self.gas_sett.heatr_ctrl = (data_array[0usize] as (i32) & 0x8i32) as (u8);
|
|
||||||
}
|
|
||||||
if desired_settings as (i32) & (64i32 | 128i32) != 0 {
|
|
||||||
self.gas_sett.nb_conv = (data_array[1usize] as (i32) & 0xfi32) as (u8);
|
|
||||||
self.gas_sett.run_gas = ((data_array[1usize] as (i32) & 0x10i32) >> 4i32) as (u8);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
rslt
|
|
||||||
|
if desired_settings as (i32) & 16i32 != 0 {
|
||||||
|
sensor_settings.tph_sett.filter =
|
||||||
|
((data_array[5usize] as (i32) & 0x1ci32) >> 2i32) as (u8);
|
||||||
|
}
|
||||||
|
|
||||||
|
if desired_settings as (i32) & (1i32 | 2i32) != 0 {
|
||||||
|
sensor_settings.tph_sett.os_temp =
|
||||||
|
((data_array[4usize] as (i32) & 0xe0i32) >> 5i32) as (u8);
|
||||||
|
sensor_settings.tph_sett.os_pres =
|
||||||
|
((data_array[4usize] as (i32) & 0x1ci32) >> 2i32) as (u8);
|
||||||
|
}
|
||||||
|
|
||||||
|
if desired_settings as (i32) & 4i32 != 0 {
|
||||||
|
sensor_settings.tph_sett.os_hum = (data_array[2usize] as (i32) & 0x7i32) as (u8);
|
||||||
|
}
|
||||||
|
|
||||||
|
if desired_settings as (i32) & 32i32 != 0 {
|
||||||
|
sensor_settings.gas_sett.heatr_ctrl = (data_array[0usize] as (i32) & 0x8i32) as (u8);
|
||||||
|
}
|
||||||
|
|
||||||
|
if desired_settings as (i32) & (64i32 | 128i32) != 0 {
|
||||||
|
sensor_settings.gas_sett.nb_conv = (data_array[1usize] as (i32) & 0xfi32) as (u8);
|
||||||
|
sensor_settings.gas_sett.run_gas =
|
||||||
|
((data_array[1usize] as (i32) & 0x10i32) >> 4i32) as (u8);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(sensor_settings)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bme680_set_sensor_mode(self) -> i8 {
|
pub fn bme680_set_sensor_mode(self, power_mode: PowerMode) -> Result<()> {
|
||||||
let mut _currentBlock;
|
|
||||||
let mut rslt: i8;
|
|
||||||
let mut tmp_pow_mode: u8;
|
let mut tmp_pow_mode: u8;
|
||||||
let mut pow_mode: u8 = 0u8;
|
let mut pow_mode: u8 = 0u8;
|
||||||
|
let mut power_mode = PowerMode::SleepMode;
|
||||||
let mut reg_addr: u8 = 0x74u8;
|
let mut reg_addr: u8 = 0x74u8;
|
||||||
_currentBlock = 1;
|
|
||||||
'loop1: loop {
|
/* Call repeatedly until in sleep */
|
||||||
if _currentBlock == 1 {
|
loop {
|
||||||
rslt = self.get_regs(
|
self.get_regs(
|
||||||
BME680_CONF_T_P_MODE_ADDR,
|
BME680_CONF_T_P_MODE_ADDR,
|
||||||
&mut tmp_pow_mode as (*mut u8),
|
&mut tmp_pow_mode as (*mut u8),
|
||||||
1u16,
|
1u16,
|
||||||
);
|
)?;
|
||||||
if rslt as (i32) == BME680_OK {
|
|
||||||
pow_mode = (tmp_pow_mode as (i32) & 0x3i32) as (u8);
|
/* Put to sleep before changing mode */
|
||||||
if pow_mode as (i32) != 0i32 {
|
pow_mode = tmp_pow_mode & BME680_MODE_MSK;
|
||||||
tmp_pow_mode = (tmp_pow_mode as (i32) & !0x3i32) as (u8);
|
|
||||||
rslt = self.bme680_set_regs(
|
if power_mode != PowerMode::SleepMode {
|
||||||
&mut reg_addr as (*mut u8) as (*const u8),
|
/* Set to sleep*/
|
||||||
&mut tmp_pow_mode as (*mut u8) as (*const u8),
|
tmp_pow_mode = tmp_pow_mode & !BME680_MODE_MSK;
|
||||||
1u8,
|
self.bme680_set_regs(
|
||||||
);
|
|
||||||
(self.delay_ms)(BME680_POLL_PERIOD_MS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if pow_mode as (i32) != BME680_SLEEP_MODE {
|
|
||||||
_currentBlock = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if !(self.power_mode as (i32) != BME680_SLEEP_MODE) {
|
|
||||||
_currentBlock = 8;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
tmp_pow_mode = (tmp_pow_mode as (i32) & !BME680_MODE_MSK
|
|
||||||
| self.power_mode as (i32) & BME680_MODE_MSK)
|
|
||||||
as (u8);
|
|
||||||
if !(rslt as (i32) == BME680_OK) {
|
|
||||||
_currentBlock = 8;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
rslt = self.bme680_set_regs(
|
|
||||||
&mut reg_addr as (*mut u8) as (*const u8),
|
&mut reg_addr as (*mut u8) as (*const u8),
|
||||||
&mut tmp_pow_mode as (*mut u8) as (*const u8),
|
&mut tmp_pow_mode as (*mut u8) as (*const u8),
|
||||||
1u8,
|
1u8,
|
||||||
);
|
)?;
|
||||||
_currentBlock = 8;
|
self.delay.delay_ms(BME680_POLL_PERIOD_MS);
|
||||||
} else {
|
} else {
|
||||||
return rslt;
|
// TODO do while in Rust?
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Already in sleep */
|
||||||
|
if power_mode != PowerMode::SleepMode {
|
||||||
|
tmp_pow_mode = tmp_pow_mode & !BME680_MODE_MSK | power_mode.value();
|
||||||
|
self.bme680_set_regs(
|
||||||
|
&mut reg_addr as (*mut u8) as (*const u8),
|
||||||
|
&mut tmp_pow_mode as (*mut u8) as (*const u8),
|
||||||
|
1u8,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_sensor_mode(self) -> i8 {
|
pub fn get_sensor_mode(self) -> Result<PowerMode> {
|
||||||
let mut mode: u8;
|
let regs = self.get_regs_u8(BME680_CONF_T_P_MODE_ADDR)?;
|
||||||
let rslt = self.get_regs(BME680_CONF_T_P_MODE_ADDR, &mut mode as (*mut u8), 1u16);
|
let mode = regs & BME680_MODE_MSK;
|
||||||
self.power_mode = (mode as (i32) & BME680_MODE_MSK) as (u8);
|
Ok(PowerMode::from(mode))
|
||||||
rslt
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bme680_set_profile_dur(self, mut duration: u16) {
|
pub fn bme680_set_profile_dur(self, mut duration: u16) {
|
||||||
|
@ -576,101 +640,100 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_sensor_data(self, mut data: *mut Bme680_field_data) -> i8 {
|
/// @returns (FieldData, IsNewFields)
|
||||||
let mut rslt: i8;
|
pub fn get_sensor_data(self) -> Result<(FieldData, FieldDataState)> {
|
||||||
rslt = self.read_field_data(data);
|
let field_data = self.read_field_data()?;
|
||||||
if rslt as (i32) == BME680_OK {
|
if field_data.status & BME680_NEW_DATA_MSK != 0 {
|
||||||
if (*data).status as (i32) & 0x80i32 != 0 {
|
// new fields
|
||||||
self.new_fields = 1u8;
|
Ok((field_data, FieldDataState::NewData))
|
||||||
} else {
|
|
||||||
self.new_fields = 0u8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rslt
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_calib_data(self) -> i8 {
|
|
||||||
let mut rslt: i8;
|
|
||||||
let mut coeff_array: [u8; 41] = 0i32 as ([u8; 41]);
|
|
||||||
let mut temp_var: u8 = 0u8;
|
|
||||||
rslt = self.get_regs(0x89u8, coeff_array.as_mut_ptr(), 25u16);
|
|
||||||
if rslt as (i32) == BME680_OK {
|
|
||||||
rslt = self.get_regs(0xe1u8, &mut coeff_array[25usize] as (*mut u8), 16u16);
|
|
||||||
}
|
|
||||||
self.calib.par_t1 = (coeff_array[34usize] as (u16) as (i32) << 8i32
|
|
||||||
| coeff_array[33usize] as (u16) as (i32)) as (u16);
|
|
||||||
self.calib.par_t2 = (coeff_array[2usize] as (u16) as (i32) << 8i32
|
|
||||||
| coeff_array[1usize] as (u16) as (i32)) as (i16);
|
|
||||||
self.calib.par_t3 = coeff_array[3usize] as (i8);
|
|
||||||
self.calib.par_p1 = (coeff_array[6usize] as (u16) as (i32) << 8i32
|
|
||||||
| coeff_array[5usize] as (u16) as (i32)) as (u16);
|
|
||||||
self.calib.par_p2 = (coeff_array[8usize] as (u16) as (i32) << 8i32
|
|
||||||
| coeff_array[7usize] as (u16) as (i32)) as (i16);
|
|
||||||
self.calib.par_p3 = coeff_array[9usize] as (i8);
|
|
||||||
self.calib.par_p4 = (coeff_array[12usize] as (u16) as (i32) << 8i32
|
|
||||||
| coeff_array[11usize] as (u16) as (i32)) as (i16);
|
|
||||||
self.calib.par_p5 = (coeff_array[14usize] as (u16) as (i32) << 8i32
|
|
||||||
| coeff_array[13usize] as (u16) as (i32)) as (i16);
|
|
||||||
self.calib.par_p6 = coeff_array[16usize] as (i8);
|
|
||||||
self.calib.par_p7 = coeff_array[15usize] as (i8);
|
|
||||||
self.calib.par_p8 = (coeff_array[20usize] as (u16) as (i32) << 8i32
|
|
||||||
| coeff_array[19usize] as (u16) as (i32)) as (i16);
|
|
||||||
self.calib.par_p9 = (coeff_array[22usize] as (u16) as (i32) << 8i32
|
|
||||||
| coeff_array[21usize] as (u16) as (i32)) as (i16);
|
|
||||||
self.calib.par_p10 = coeff_array[23usize];
|
|
||||||
self.calib.par_h1 = (coeff_array[27usize] as (u16) as (i32) << 4i32
|
|
||||||
| coeff_array[26usize] as (i32) & 0xfi32) as (u16);
|
|
||||||
self.calib.par_h2 = (coeff_array[25usize] as (u16) as (i32) << 4i32
|
|
||||||
| coeff_array[26usize] as (i32) >> 4i32) as (u16);
|
|
||||||
self.calib.par_h3 = coeff_array[28usize] as (i8);
|
|
||||||
self.calib.par_h4 = coeff_array[29usize] as (i8);
|
|
||||||
self.calib.par_h5 = coeff_array[30usize] as (i8);
|
|
||||||
self.calib.par_h6 = coeff_array[31usize];
|
|
||||||
self.calib.par_h7 = coeff_array[32usize] as (i8);
|
|
||||||
self.calib.par_gh1 = coeff_array[37usize] as (i8);
|
|
||||||
self.calib.par_gh2 = (coeff_array[36usize] as (u16) as (i32) << 8i32
|
|
||||||
| coeff_array[35usize] as (u16) as (i32)) as (i16);
|
|
||||||
self.calib.par_gh3 = coeff_array[38usize] as (i8);
|
|
||||||
if rslt as (i32) == BME680_OK {
|
|
||||||
rslt = self.get_regs(0x2u8, &mut temp_var as (*mut u8), 1u16);
|
|
||||||
self.calib.res_heat_range = ((temp_var as (i32) & 0x30i32) / 16i32) as (u8);
|
|
||||||
if rslt as (i32) == BME680_OK {
|
|
||||||
rslt = self.get_regs(0x0u8, &mut temp_var as (*mut u8), 1u16);
|
|
||||||
self.calib.res_heat_val = temp_var as (i8);
|
|
||||||
if rslt as (i32) == BME680_OK {
|
|
||||||
rslt = self.get_regs(0x4u8, &mut temp_var as (*mut u8), 1u16);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.calib.range_sw_err = ((temp_var as (i8) as (i32) & 0xf0i32) / 16i32) as (i8);
|
|
||||||
rslt
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_gas_config(self) -> i8 {
|
|
||||||
let mut rslt: i8;
|
|
||||||
let mut reg_addr: [u8; 2] = 0i32 as ([u8; 2]);
|
|
||||||
let mut reg_data: [u8; 2] = 0i32 as ([u8; 2]);
|
|
||||||
if self.power_mode as (i32) == 1i32 {
|
|
||||||
reg_addr[0usize] = 0x5au8;
|
|
||||||
reg_data[0usize] = self.calc_heater_res(self.gas_sett.heatr_temp);
|
|
||||||
reg_addr[1usize] = 0x64u8;
|
|
||||||
reg_data[1usize] = self.calc_heater_dur(self.gas_sett.heatr_dur);
|
|
||||||
self.gas_sett.nb_conv = 0u8;
|
|
||||||
} else {
|
} else {
|
||||||
rslt = 1i8;
|
Ok((field_data, FieldDataState::NoNewData))
|
||||||
}
|
}
|
||||||
if rslt as (i32) == BME680_OK {
|
|
||||||
rslt = self.bme680_set_regs(
|
|
||||||
reg_addr.as_mut_ptr() as (*const u8),
|
|
||||||
reg_data.as_mut_ptr() as (*const u8),
|
|
||||||
2u8,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
rslt
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_gas_config(self) -> Result<Bme680_gas_sett> {
|
fn get_calib_data(self) -> Result<CalibData> {
|
||||||
let mut gas_sett: Bme680_gas_sett = Default::default();
|
let mut calib: CalibData = Default::default();
|
||||||
|
let mut coeff_array: [u8; BME680_COEFF_SIZE] = [0; BME680_COEFF_SIZE];
|
||||||
|
|
||||||
|
self.get_regs(
|
||||||
|
BME680_COEFF_ADDR1,
|
||||||
|
coeff_array.as_mut_ptr(),
|
||||||
|
BME680_COEFF_ADDR1_LEN,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
self.get_regs(
|
||||||
|
BME680_COEFF_ADDR2,
|
||||||
|
&mut coeff_array[25usize] as (*mut u8),
|
||||||
|
BME680_COEFF_ADDR2_LEN,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
calib.par_t1 = (coeff_array[34usize] as (u16) as (i32) << 8i32
|
||||||
|
| coeff_array[33usize] as (u16) as (i32)) as (u16);
|
||||||
|
calib.par_t2 = (coeff_array[2usize] as (u16) as (i32) << 8i32
|
||||||
|
| coeff_array[1usize] as (u16) as (i32)) as (i16);
|
||||||
|
calib.par_t3 = coeff_array[3usize] as (i8);
|
||||||
|
calib.par_p1 = (coeff_array[6usize] as (u16) as (i32) << 8i32
|
||||||
|
| coeff_array[5usize] as (u16) as (i32)) as (u16);
|
||||||
|
calib.par_p2 = (coeff_array[8usize] as (u16) as (i32) << 8i32
|
||||||
|
| coeff_array[7usize] as (u16) as (i32)) as (i16);
|
||||||
|
calib.par_p3 = coeff_array[9usize] as (i8);
|
||||||
|
calib.par_p4 = (coeff_array[12usize] as (u16) as (i32) << 8i32
|
||||||
|
| coeff_array[11usize] as (u16) as (i32)) as (i16);
|
||||||
|
calib.par_p5 = (coeff_array[14usize] as (u16) as (i32) << 8i32
|
||||||
|
| coeff_array[13usize] as (u16) as (i32)) as (i16);
|
||||||
|
calib.par_p6 = coeff_array[16usize] as (i8);
|
||||||
|
calib.par_p7 = coeff_array[15usize] as (i8);
|
||||||
|
calib.par_p8 = (coeff_array[20usize] as (u16) as (i32) << 8i32
|
||||||
|
| coeff_array[19usize] as (u16) as (i32)) as (i16);
|
||||||
|
calib.par_p9 = (coeff_array[22usize] as (u16) as (i32) << 8i32
|
||||||
|
| coeff_array[21usize] as (u16) as (i32)) as (i16);
|
||||||
|
calib.par_p10 = coeff_array[23usize];
|
||||||
|
calib.par_h1 = (coeff_array[27usize] as (u16) as (i32) << 4i32
|
||||||
|
| coeff_array[26usize] as (i32) & 0xfi32) as (u16);
|
||||||
|
calib.par_h2 = (coeff_array[25usize] as (u16) as (i32) << 4i32
|
||||||
|
| coeff_array[26usize] as (i32) >> 4i32) as (u16);
|
||||||
|
calib.par_h3 = coeff_array[28usize] as (i8);
|
||||||
|
calib.par_h4 = coeff_array[29usize] as (i8);
|
||||||
|
calib.par_h5 = coeff_array[30usize] as (i8);
|
||||||
|
calib.par_h6 = coeff_array[31usize];
|
||||||
|
calib.par_h7 = coeff_array[32usize] as (i8);
|
||||||
|
calib.par_gh1 = coeff_array[37usize] as (i8);
|
||||||
|
calib.par_gh2 = (coeff_array[36usize] as (u16) as (i32) << 8i32
|
||||||
|
| coeff_array[35usize] as (u16) as (i32)) as (i16);
|
||||||
|
calib.par_gh3 = coeff_array[38usize] as (i8);
|
||||||
|
|
||||||
|
calib.res_heat_range = (self.get_regs_u8(BME680_ADDR_RES_HEAT_RANGE_ADDR)? & 0x30) / 16;
|
||||||
|
|
||||||
|
calib.res_heat_val = self.get_regs_i8(BME680_ADDR_RES_HEAT_VAL_ADDR)?;
|
||||||
|
|
||||||
|
calib.range_sw_err = (self.get_regs_i8(BME680_ADDR_RANGE_SW_ERR_ADDR)? & 0xf0) / 16;
|
||||||
|
|
||||||
|
Ok(calib)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_gas_config(&self, gas_sett: GasSett) -> Result<()> {
|
||||||
|
let mut reg_addr: [u8; 2] = [0; 2];
|
||||||
|
let mut reg_data: [u8; 2] = [0; 2];
|
||||||
|
|
||||||
|
if self.power_mode != PowerMode::ForcedMode {
|
||||||
|
return Err(Bme680Error::DefinePwrMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
reg_addr[0] = BME680_RES_HEAT0_ADDR;
|
||||||
|
reg_data[0] = self.calc_heater_res(gas_sett.heatr_temp);
|
||||||
|
reg_addr[1] = BME680_GAS_WAIT0_ADDR;
|
||||||
|
reg_data[1] = self.calc_heater_dur(gas_sett.heatr_dur);
|
||||||
|
|
||||||
|
self.gas_sett.nb_conv = 0;
|
||||||
|
self.bme680_set_regs(
|
||||||
|
reg_addr.as_mut_ptr() as (*const u8),
|
||||||
|
reg_data.as_mut_ptr() as (*const u8),
|
||||||
|
2,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_gas_config(self) -> Result<GasSett> {
|
||||||
|
let mut gas_sett: GasSett = Default::default();
|
||||||
// TODO figure out if heat_temp and dur can be u8
|
// TODO figure out if heat_temp and dur can be u8
|
||||||
self.gas_sett.heatr_temp = self.get_regs_u8(BME680_ADDR_SENS_CONF_START)? as u16;
|
self.gas_sett.heatr_temp = self.get_regs_u8(BME680_ADDR_SENS_CONF_START)? as u16;
|
||||||
self.gas_sett.heatr_dur = self.get_regs_u8(BME680_ADDR_GAS_CONF_START)? as u16;
|
self.gas_sett.heatr_dur = self.get_regs_u8(BME680_ADDR_GAS_CONF_START)? as u16;
|
||||||
|
@ -678,35 +741,29 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
fn calc_heater_res(self, mut temp: u16) -> u8 {
|
fn calc_heater_res(self, mut temp: u16) -> u8 {
|
||||||
let mut heatr_res: u8;
|
// cap temperature
|
||||||
let mut var1: i32;
|
|
||||||
let mut var2: i32;
|
|
||||||
let mut var3: i32;
|
|
||||||
let mut var4: i32;
|
|
||||||
let mut var5: i32;
|
|
||||||
let mut heatr_res_x100: i32;
|
|
||||||
if temp as (i32) > 400i32 {
|
if temp as (i32) > 400i32 {
|
||||||
temp = 400u16;
|
temp = 400u16;
|
||||||
}
|
}
|
||||||
var1 = self.amb_temp as (i32) * self.calib.par_gh3 as (i32) / 1000i32 * 256i32;
|
|
||||||
var2 = (self.calib.par_gh1 as (i32) + 784i32)
|
let var1 = self.amb_temp as (i32) * self.calib.par_gh3 as (i32) / 1000i32 * 256i32;
|
||||||
|
let var2 = (self.calib.par_gh1 as (i32) + 784i32)
|
||||||
* (((self.calib.par_gh2 as (i32) + 154009i32) * temp as (i32) * 5i32 / 100i32
|
* (((self.calib.par_gh2 as (i32) + 154009i32) * temp as (i32) * 5i32 / 100i32
|
||||||
+ 3276800i32) / 10i32);
|
+ 3276800i32) / 10i32);
|
||||||
var3 = var1 + var2 / 2i32;
|
let var3 = var1 + var2 / 2i32;
|
||||||
var4 = var3 / (self.calib.res_heat_range as (i32) + 4i32);
|
let var4 = var3 / (self.calib.res_heat_range as (i32) + 4i32);
|
||||||
var5 = 131i32 * self.calib.res_heat_val as (i32) + 65536i32;
|
let var5 = 131i32 * self.calib.res_heat_val as (i32) + 65536i32;
|
||||||
heatr_res_x100 = (var4 / var5 - 250i32) * 34i32;
|
let heatr_res_x100 = (var4 / var5 - 250i32) * 34i32;
|
||||||
heatr_res = ((heatr_res_x100 + 50i32) / 100i32) as (u8);
|
((heatr_res_x100 + 50i32) / 100i32) as (u8)
|
||||||
heatr_res
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn calc_heater_dur(mut dur: u16) -> u8 {
|
fn calc_heater_dur(&self, mut dur: u16) -> u8 {
|
||||||
let mut factor: u8 = 0u8;
|
let mut factor: u8 = 0u8;
|
||||||
let mut durval: u8;
|
let mut durval: u8;
|
||||||
if dur as (i32) >= 0xfc0i32 {
|
if dur as (i32) >= 0xfc0i32 {
|
||||||
durval = 0xffu8;
|
durval = 0xffu8; // Max duration
|
||||||
} else {
|
} else {
|
||||||
'loop1: loop {
|
loop {
|
||||||
if !(dur as (i32) > 0x3fi32) {
|
if !(dur as (i32) > 0x3fi32) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -837,11 +894,10 @@ where
|
||||||
calc_gas_res
|
calc_gas_res
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_field_data(self) -> Result<Bme680_field_data> {
|
fn read_field_data(self) -> Result<FieldData> {
|
||||||
let mut _currentBlock;
|
let mut _currentBlock;
|
||||||
let mut rslt: i8;
|
|
||||||
let mut buff = [0, BME680_FIELD_LENGTH];
|
let mut buff = [0, BME680_FIELD_LENGTH];
|
||||||
let mut data: Bme680_field_data = Default::default();
|
let mut data: FieldData = Default::default();
|
||||||
let mut gas_range: u8;
|
let mut gas_range: u8;
|
||||||
let mut adc_temp: u32;
|
let mut adc_temp: u32;
|
||||||
let mut adc_pres: u32;
|
let mut adc_pres: u32;
|
||||||
|
@ -885,20 +941,20 @@ where
|
||||||
Err(Bme680Error::NoNewData)
|
Err(Bme680Error::NoNewData)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn boundary_check(self, mut value: *mut u8, mut min: u8, mut max: u8) -> i8 {
|
fn boundary_check(self, value: u8, min: u8, max: u8) -> Result<()> {
|
||||||
let mut rslt: i8 = 0i8;
|
let info_msg: InfoMsg = Default::default();
|
||||||
if value != 0i32 as (*mut ::std::os::raw::c_void) as (*mut u8) {
|
|
||||||
if *value as (i32) < min as (i32) {
|
if value < min {
|
||||||
*value = min;
|
info_msg |= InfoMsg::MIN_CORRECTION;
|
||||||
self.info_msg = (self.info_msg as (i32) | 1i32) as (u8);
|
|
||||||
}
|
|
||||||
if *value as (i32) > max as (i32) {
|
|
||||||
*value = max;
|
|
||||||
self.info_msg = (self.info_msg as (i32) | 2i32) as (u8);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
rslt = -1i8;
|
|
||||||
}
|
}
|
||||||
rslt
|
|
||||||
|
if value > max {
|
||||||
|
info_msg |= InfoMsg::MAX_CORRECTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
if info_msg.is_empty() {
|
||||||
|
return Err(Bme680Error::BoundaryCheckFailure(info_msg, min, max));
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,3 +21,14 @@ pub const BME680_MEM_PAGE0: u8 = 0x10;
|
||||||
/// SPI memory page settings
|
/// SPI memory page settings
|
||||||
///
|
///
|
||||||
pub const BME680_MEM_PAGE1: u8 = 0x00;
|
pub const BME680_MEM_PAGE1: u8 = 0x00;
|
||||||
|
|
||||||
|
/* Settings selector */
|
||||||
|
pub const BME680_OST_SEL: u16 = 1;
|
||||||
|
pub const BME680_OSP_SEL: u16 = 2;
|
||||||
|
pub const BME680_OSH_SEL: u16 = 4;
|
||||||
|
pub const BME680_GAS_MEAS_SEL: u16 = 8;
|
||||||
|
pub const BME680_FILTER_SEL: u16 = 16;
|
||||||
|
pub const BME680_HCNTRL_SEL: u16 = 32;
|
||||||
|
pub const BME680_RUN_GAS_SEL: u16 = 64;
|
||||||
|
pub const BME680_NBCONV_SEL: u16 = 128;
|
||||||
|
pub const BME680_GAS_SENSOR_SEL: u16 = BME680_GAS_MEAS_SEL | BME680_RUN_GAS_SEL | BME680_NBCONV_SEL;
|
||||||
|
|
|
@ -2,8 +2,9 @@
|
||||||
#![allow(non_camel_case_types)]
|
#![allow(non_camel_case_types)]
|
||||||
#![allow(non_snake_case)]
|
#![allow(non_snake_case)]
|
||||||
#![feature(rustc_private)]
|
#![feature(rustc_private)]
|
||||||
|
#![feature(try_from)]
|
||||||
|
|
||||||
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
|
//include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate bitflags;
|
extern crate bitflags;
|
||||||
|
@ -13,7 +14,6 @@ extern crate byteorder;
|
||||||
extern crate embedded_hal as hal;
|
extern crate embedded_hal as hal;
|
||||||
|
|
||||||
use hal::blocking::delay::{DelayMs, DelayUs};
|
use hal::blocking::delay::{DelayMs, DelayUs};
|
||||||
use hal::blocking::i2c::{Read, Write, WriteRead};
|
|
||||||
use std::result;
|
use std::result;
|
||||||
|
|
||||||
#[link(name = "example", kind = "static")]
|
#[link(name = "example", kind = "static")]
|
||||||
|
|
Loading…
Reference in a new issue