From b213d691c6ea00a39c25c54b9574ff6a8109c9b9 Mon Sep 17 00:00:00 2001 From: marcelbuesing Date: Sun, 15 Apr 2018 21:31:46 +0200 Subject: [PATCH] Add missing device functions --- Cargo.lock | 1 + Cargo.toml | 1 + src/device_builder.rs | 155 +++++++++++++++++++++++++++++++++++++++++- src/lib.rs | 45 +++++++++++- 4 files changed, 199 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 59f04d1..1413928 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -52,6 +52,7 @@ name = "bme680-rs" version = "0.1.0" dependencies = [ "bindgen 0.35.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/Cargo.toml b/Cargo.toml index 2bc9c69..11cab5d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,4 +8,5 @@ authors = ["marcelbuesing "] [build-dependencies] bindgen = "0.35.0" +bitflags = "1.0.1" gcc = "0.3.54" diff --git a/src/device_builder.rs b/src/device_builder.rs index e94dd52..774477f 100644 --- a/src/device_builder.rs +++ b/src/device_builder.rs @@ -1,6 +1,29 @@ use consts; -use {to_result, Result, bme680_calib_data, bme680_dev, bme680_gas_sett, bme680_init, bme680_intf, - bme680_intf_BME680_I2C_INTF, bme680_tph_sett}; +use {to_result, PowerMode, Result, SensorSettings, bme680_calib_data, bme680_dev, + bme680_field_data, bme680_gas_sett, bme680_get_profile_dur, bme680_get_regs, + bme680_get_sensor_data, bme680_get_sensor_mode, bme680_get_sensor_settings, bme680_init, + bme680_intf, bme680_intf_BME680_I2C_INTF, bme680_set_profile_dur, bme680_set_sensor_mode, + bme680_set_sensor_settings, bme680_soft_reset, bme680_tph_sett}; + +impl Default for bme680_field_data { + fn default() -> bme680_field_data { + bme680_field_data { + status: Default::default(), + /// The index of the heater profile used + gas_index: Default::default(), + /// Measurement index to track order + meas_index: Default::default(), + /// Temperature in degree celsius x100 + temperature: Default::default(), + /// Pressure in Pascal + pressure: Default::default(), + /// Humidity in % relative humidity x1000 + humidity: Default::default(), + /// Gas resistance in Ohms + gas_resistance: Default::default(), + } + } +} pub struct Bme680Device { dev: bme680_dev, @@ -17,6 +40,134 @@ impl Bme680Device { let dev_ptr: *mut bme680_dev = &mut self.dev; unsafe { to_result(bme680_init(dev_ptr)) } } + + /// @brief This API writes the given data to the register address + /// of the sensor. + /// + /// @param[in] reg_addr : Register address from where the data to be written. + /// @param[in] reg_data : Pointer to data buffer which is to be written + /// in the sensor. + /// @param[in] len : No of bytes of data to write.. + /// @param[in] dev : Structure instance of bme680_dev. + /// + /// @return Result of API execution status + pub fn set_regs(mut self, reg_addr: u8, reg_data: &mut [u8]) -> Result<()> { + let dev_ptr: *mut bme680_dev = &mut self.dev; + unsafe { + to_result(bme680_get_regs( + reg_addr, + reg_data.as_mut_ptr(), + reg_data.len() as u16, + dev_ptr, + )) + } + } + /// @brief This API reads the data from the given register address of the sensor. + /// + /// @param[in] reg_addr : Register address from where the data to be read + /// @param[out] reg_data : buffer to store the read data. + /// + /// @return Result of API execution status + pub fn get_regs(mut self, reg_addr: u8, reg_data: &mut [u8]) -> Result<()> { + let dev_ptr: *mut bme680_dev = &mut self.dev; + unsafe { + to_result(bme680_get_regs( + reg_addr, + reg_data.as_mut_ptr(), + reg_data.len() as u16, + dev_ptr, + )) + } + } + /// @brief This API performs the soft reset of the sensor. + /// + /// @return Result of API execution status + pub fn soft_reset(mut self) -> Result<()> { + let dev_ptr: *mut bme680_dev = &mut self.dev; + unsafe { to_result(bme680_soft_reset(dev_ptr)) } + } + + /// @brief This API is used to set the power mode of the sensor. + /// + /// @param[in] power_mode : Sensor power mode + /// + /// @return Result of API execution status + pub fn set_sensor_mode(mut self, power_mode: PowerMode) -> Result<()> { + self.dev.power_mode = power_mode.value(); + let dev_ptr: *mut bme680_dev = &mut self.dev; + unsafe { to_result(bme680_set_sensor_mode(dev_ptr)) } + } + + /// @brief This API is used to get the power mode of the sensor. + /// + /// @return Sensor power mode + pub fn get_sensor_mode(mut self) -> Result { + let dev_ptr: *mut bme680_dev = &mut self.dev; + let r = unsafe { to_result(bme680_get_sensor_mode(dev_ptr)) }; + r.map(|_| PowerMode::from(self.dev.power_mode)) + } + + /// @brief This API is used to set the profile duration of the sensor. + /// + /// @param[in] duration : Duration of the measurement in ms. + pub fn set_profile_dur(mut self, duration: u16) { + let dev_ptr: *mut bme680_dev = &mut self.dev; + unsafe { bme680_set_profile_dur(duration, dev_ptr) } + } + + /// @brief This API is used to get the profile duration of the sensor. + /// + /// @return Duration of the measurement in ms. + pub fn get_profile_dur(mut self) -> u16 { + let dev_ptr: *mut bme680_dev = &mut self.dev; + let mut duration = 0; + unsafe { bme680_get_profile_dur(&mut duration, dev_ptr) }; + duration + } + + /// @brief This API reads the pressure, temperature and humidity and gas data + /// from the sensor, compensates the data and store it in the bme680_data + /// structure instance passed by the user. + /// + /// @param[out] data: Structure instance to hold the data. + /// @param[in] dev : Structure instance of bme680_dev. + /// + /// @return Result of API execution status + pub fn get_sensor_data(mut self) -> Result { + let dev_ptr: *mut bme680_dev = &mut self.dev; + let mut field_data = Default::default(); + let field_data_ptr: *mut bme680_field_data = &mut field_data; + let r = unsafe { to_result(bme680_get_sensor_data(field_data_ptr, dev_ptr)) }; + r.map(|_| field_data) + } + + /// @brief This API is used to set the oversampling, filter and T,P,H, gas selection + /// settings in the sensor. + /// + /// @param[in] desired_settings : Variable used to select the settings which + /// @return Result of API execution status + + pub fn set_sensor_settings(mut self, sensor_settings: SensorSettings) -> Result<()> { + let dev_ptr: *mut bme680_dev = &mut self.dev; + unsafe { to_result(bme680_set_sensor_settings(sensor_settings.bits(), dev_ptr)) } + } + + pub fn get_tph_sett(mut self) -> Result { + let dev_ptr: *mut bme680_dev = &mut self.dev; + let settings_sel = SensorSettings::OST_SEL | SensorSettings::OSP_SEL + | SensorSettings::OSH_SEL | SensorSettings::FILTER_SEL; + + let r = unsafe { to_result(bme680_get_sensor_settings(settings_sel.bits(), dev_ptr)) }; + r.map(|_| self.dev.tph_sett) + } + + pub fn get_gas_sett(mut self) -> Result { + let dev_ptr: *mut bme680_dev = &mut self.dev; + let settings_sel = SensorSettings::GAS_SENSOR_SEL; + + let r = unsafe { to_result(bme680_get_sensor_settings(settings_sel.bits(), dev_ptr)) }; + r.map(|_| self.dev.gas_sett) + } } impl Default for bme680_calib_data { diff --git a/src/lib.rs b/src/lib.rs index ecde95c..c3ff53b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,10 +1,13 @@ #![allow(non_upper_case_globals)] #![allow(non_camel_case_types)] #![allow(non_snake_case)] +#![feature(rustc_private)] include!(concat!(env!("OUT_DIR"), "/bindings.rs")); -use std::default::Default; +#[macro_use] +extern crate bitflags; + use std::result; #[link(name = "example", kind = "static")] @@ -75,3 +78,43 @@ pub enum PowerMode { SleepMode, ForcedMode, } + +impl PowerMode { + fn from(power_mode: u8) -> Self { + match power_mode { + consts::BME680_SLEEP_MODE => PowerMode::SleepMode, + consts::BME680_FORCED_MODE => PowerMode::ForcedMode, + _ => panic!("Unknown power mode: {}", power_mode), + } + } + + fn value(&self) -> u8 { + match self { + PowerMode::SleepMode => consts::BME680_SLEEP_MODE, + PowerMode::ForcedMode => consts::BME680_FORCED_MODE, + } + } +} + +bitflags! { + pub struct SensorSettings: 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; + } +}