2 #if RI_BME280_ENABLED || DOXYGEN
19 #include "bme280_defs.h"
20 #include "bme280_selftest.h"
21 #if !(BME280_FLOAT_ENABLE || DOXYGEN)
22 #error "Please #define BME280_FLOAT_ENABLE in makefile CFLAGS"
40 #define BME280_MEAS_TIME_CONST1 (1.25F)
41 #define BME280_MEAS_TIME_CONST2 (2.3F)
42 #define BME280_MEAS_TIME_CONST3 (3.0F)
43 #define BME280_MEAS_TIME_CONST4 (2.0F)
44 #define BME280_MEAS_TIME_CONST5 (0.575F)
45 #define BME280_MEAS_TIME_CONST6 (2U)
47 #define BME280_SAMPLERATE_1000MS (1U)
48 #define BME280_SAMPLERATE_500MS (2U)
49 #define BME280_SAMPLERATE_125MS (8U)
50 #define BME280_SAMPLERATE_62_5MS (16U)
51 #define BME280_SAMPLERATE_20MS (50U)
52 #define BME280_SAMPLERATE_10MS (100U)
53 #define BME280_SAMPLERATE_0_5MS (200U)
55 #define BME280_DSP_MODE_0 (1U)
56 #define BME280_DSP_MODE_1 (2U)
57 #define BME280_DSP_MODE_2 (4U)
58 #define BME280_DSP_MODE_3 (8U)
59 #define BME280_DSP_MODE_4 (16U)
61 #define BME280_HUMIDITY (0)
62 #define BME280_PRESSURE (1)
63 #define BME280_TEMPERATURE (2)
64 #define BME280_SENS_NUM (3)
66 #define BME280_HUMIDITY_MAX_VALUE (100.0f)
74 struct bme280_dev dev = {0};
75 static uint64_t tsample;
76 static const char m_sensor_name[] =
"BME280";
97 static rd_status_t bme280_success_on_valid (uint8_t param)
115 static rd_status_t BME_TO_RUUVI_ERROR (int8_t rslt)
119 if (BME280_OK == rslt) { err_code =
RD_SUCCESS; }
121 else if (BME280_E_NULL_PTR == rslt) { err_code =
RD_ERROR_NULL; }
122 else if (BME280_E_COMM_FAIL == rslt) { err_code =
RD_ERROR_BUSY; }
137 uint32_t bme280_max_meas_time (
const uint8_t oversampling)
144 uint32_t ret_time = (uint32_t) rd_time;
152 rd_status_t bme280_spi_init (
const struct bme280_dev *
const p_dev,
const uint8_t handle)
156 #if RI_BME280_SPI_ENABLED
158 dev.intf = BME280_SPI_INTF;
162 err_code = BME_TO_RUUVI_ERROR (bme280_init (&dev));
170 rd_status_t bme280_i2c_init (
const struct bme280_dev *
const p_dev,
const uint8_t handle)
174 #if RI_BME280_I2C_ENABLED
176 dev.intf = BME280_I2C_INTF;
180 err_code = BME_TO_RUUVI_ERROR (bme280_init (&dev));
185 static void bme280_ri_setup (
rd_sensor_t *
const environmental_sensor)
213 if (NULL == p_sensor)
224 p_sensor->
name = m_sensor_name;
228 err_code |= bme280_spi_init (&dev, handle);
232 err_code |= bme280_i2c_init (&dev, handle);
241 err_code |= BME_TO_RUUVI_ERROR (bme280_soft_reset (&dev));
244 uint8_t dsp_parameter = 1;
250 bme280_ri_setup (p_sensor);
270 err_code = BME_TO_RUUVI_ERROR (bme280_soft_reset (&dev));
275 memset (&dev, 0,
sizeof (dev));
286 rd_status_t ri2bme_rate (
struct bme280_dev * p_dev, uint8_t *
const samplerate)
290 if (
RD_SENSOR_CFG_DEFAULT == *samplerate) { p_dev->settings.standby_time = BME280_STANDBY_TIME_1000_MS; }
292 else if (
BME280_SAMPLERATE_500MS == *samplerate) { p_dev->settings.standby_time = BME280_STANDBY_TIME_500_MS; }
293 else if (*samplerate <=
BME280_SAMPLERATE_125MS) { p_dev->settings.standby_time = BME280_STANDBY_TIME_125_MS; }
295 else if (*samplerate <=
BME280_SAMPLERATE_20MS) { p_dev->settings.standby_time = BME280_STANDBY_TIME_20_MS; }
296 else if (*samplerate <=
BME280_SAMPLERATE_10MS) { p_dev->settings.standby_time = BME280_STANDBY_TIME_10_MS; }
297 else if (*samplerate <=
BME280_SAMPLERATE_0_5MS) { p_dev->settings.standby_time = BME280_STANDBY_TIME_0_5_MS; }
298 else if (
RD_SENSOR_CFG_MIN == *samplerate) { p_dev->settings.standby_time = BME280_STANDBY_TIME_1000_MS; }
299 else if (
RD_SENSOR_CFG_MAX == *samplerate) { p_dev->settings.standby_time = BME280_STANDBY_TIME_0_5_MS; }
316 if (NULL == samplerate)
320 else if (
RD_SUCCESS == bme280_verify_sensor_sleep())
322 err_code = ri2bme_rate (&dev, samplerate);
326 err_code |= BME_TO_RUUVI_ERROR (bme280_set_sensor_settings (BME280_STANDBY_SEL, &dev));
342 if (NULL == samplerate)
348 err_code = BME_TO_RUUVI_ERROR (bme280_get_sensor_settings (&dev));
352 if (BME280_STANDBY_TIME_1000_MS == dev.settings.standby_time)
356 else if (BME280_STANDBY_TIME_500_MS == dev.settings.standby_time)
360 else if (BME280_STANDBY_TIME_125_MS == dev.settings.standby_time)
364 else if (BME280_STANDBY_TIME_62_5_MS == dev.settings.standby_time)
368 else if (BME280_STANDBY_TIME_20_MS == dev.settings.standby_time)
372 else if (BME280_STANDBY_TIME_10_MS == dev.settings.standby_time)
376 else if (BME280_STANDBY_TIME_0_5_MS == dev.settings.standby_time)
394 if (NULL == resolution)
400 err_code = bme280_verify_sensor_sleep();
404 uint8_t original = *resolution;
406 err_code = bme280_success_on_valid (original);
422 if (NULL == resolution)
444 err_code = bme280_verify_sensor_sleep();
448 uint8_t original = *scale;
450 err_code = bme280_success_on_valid (original);
478 static rd_status_t ri_bme280_dsp_setup_over (uint8_t * parameter)
486 dev.settings.osr_h = BME280_OVERSAMPLING_1X;
487 dev.settings.osr_p = BME280_OVERSAMPLING_1X;
488 dev.settings.osr_t = BME280_OVERSAMPLING_1X;
493 dev.settings.osr_h = BME280_OVERSAMPLING_2X;
494 dev.settings.osr_p = BME280_OVERSAMPLING_2X;
495 dev.settings.osr_t = BME280_OVERSAMPLING_2X;
500 dev.settings.osr_h = BME280_OVERSAMPLING_4X;
501 dev.settings.osr_p = BME280_OVERSAMPLING_4X;
502 dev.settings.osr_t = BME280_OVERSAMPLING_4X;
507 dev.settings.osr_h = BME280_OVERSAMPLING_8X;
508 dev.settings.osr_p = BME280_OVERSAMPLING_8X;
509 dev.settings.osr_t = BME280_OVERSAMPLING_8X;
515 dev.settings.osr_h = BME280_OVERSAMPLING_16X;
516 dev.settings.osr_p = BME280_OVERSAMPLING_16X;
517 dev.settings.osr_t = BME280_OVERSAMPLING_16X;
529 static rd_status_t ri_bme280_dsp_setup (uint8_t * p_settings_sel,
const uint8_t * dsp,
543 dev.settings.osr_h = BME280_OVERSAMPLING_1X;
544 dev.settings.osr_p = BME280_OVERSAMPLING_1X;
545 dev.settings.osr_t = BME280_OVERSAMPLING_1X;
546 dev.settings.filter = BME280_FILTER_COEFF_OFF;
547 *p_settings_sel |= BME280_OSR_PRESS_SEL;
548 *p_settings_sel |= BME280_OSR_TEMP_SEL;
549 *p_settings_sel |= BME280_OSR_HUM_SEL;
550 *p_settings_sel |= BME280_FILTER_SEL;
559 dev.settings.filter = BME280_FILTER_COEFF_OFF;
564 dev.settings.filter = BME280_FILTER_COEFF_2;
569 dev.settings.filter = BME280_FILTER_COEFF_4;
574 dev.settings.filter = BME280_FILTER_COEFF_8;
580 dev.settings.filter = BME280_FILTER_COEFF_16;
593 err_code = ri_bme280_dsp_setup_over (parameter);
603 uint8_t settings_sel = 0U;
605 if ( (NULL == dsp) || (NULL == parameter))
611 err_code = bme280_verify_sensor_sleep();
641 err_code = ri_bme280_dsp_setup (&settings_sel, dsp, parameter);
649 err_code = BME_TO_RUUVI_ERROR (bme280_set_sensor_settings (settings_sel, &dev));
655 static void ri_bme280_dsp_get_param (uint8_t * dsp, uint8_t * parameter)
662 if (BME280_FILTER_COEFF_OFF != dev.settings.filter)
666 switch (dev.settings.filter)
668 case BME280_FILTER_COEFF_2:
672 case BME280_FILTER_COEFF_4:
676 case BME280_FILTER_COEFF_8:
680 case BME280_FILTER_COEFF_16:
693 if ( (BME280_NO_OVERSAMPLING != dev.settings.osr_h)
694 && (BME280_OVERSAMPLING_1X != dev.settings.osr_h))
698 switch (dev.settings.osr_h)
700 case BME280_OVERSAMPLING_2X:
704 case BME280_OVERSAMPLING_4X:
708 case BME280_OVERSAMPLING_8X:
712 case BME280_OVERSAMPLING_16X:
728 if ( (NULL == dsp) || (NULL == parameter))
734 err_code |= BME_TO_RUUVI_ERROR (bme280_get_sensor_settings (&dev));
738 ri_bme280_dsp_get_param (dsp, parameter);
745 static rd_status_t ri_bme280_mode_set_single (uint8_t * mode)
759 err_code = BME_TO_RUUVI_ERROR (bme280_set_sensor_mode (BME280_FORCED_MODE, &dev));
763 uint8_t samples = (uint8_t) (1U << (dev.settings.osr_h - 1U));
786 err_code = BME_TO_RUUVI_ERROR (bme280_set_sensor_mode (BME280_SLEEP_MODE, &dev));
790 err_code = ri_bme280_mode_set_single (mode);
794 err_code = BME_TO_RUUVI_ERROR (bme280_set_sensor_mode (BME280_NORMAL_MODE, &dev));
816 uint8_t bme_mode = 0U;
817 err_code = BME_TO_RUUVI_ERROR (bme280_get_sensor_mode (&bme_mode, &dev));
823 case BME280_SLEEP_MODE:
827 case BME280_FORCED_MODE:
831 case BME280_NORMAL_MODE:
845 static void ri_bme280_check_humiduty (
float * p_value)
864 struct bme280_data comp_data;
865 err_code = BME_TO_RUUVI_ERROR (bme280_get_sensor_data (BME280_ALL, &comp_data, &dev));
891 d_environmental.
data = env_values;
892 d_environmental.
fields = env_fields;
893 d_environmental.
valid = env_fields;
#define RD_ERROR_INVALID_PARAM
Invalid Parameter.
#define RD_ERROR_NULL
Null Pointer.
#define RD_ERROR_FATAL
Program should always reset after this.
uint32_t rd_status_t
bitfield for representing errors
#define RD_ERROR_CHECK(error, mask)
Shorthand macro for calling the rd_error_check with current file & line.
#define RD_ERROR_NOT_ENABLED
Driver is not enabled.
#define RD_ERROR_NOT_SUPPORTED
Not supported.
#define RD_SUCCESS
Internal Error.
#define RD_ERROR_NOT_FOUND
Not found.
#define RD_UINT64_INVALID
Signal that value should not be used.
#define RD_ERROR_INVALID_STATE
Invalid state, operation disallowed in this state.
#define RD_ERROR_INTERNAL
Internal Error.
#define RD_ERROR_BUSY
Busy.
int8_t ri_i2c_bme280_read(uint8_t dev_id, uint8_t reg_addr, uint8_t *p_reg_data, uint16_t len)
I2C Read function for BME280.
int8_t ri_i2c_bme280_write(uint8_t dev_id, uint8_t reg_addr, uint8_t *p_reg_data, uint16_t len)
I2C write function for BME280.
int8_t ri_spi_bme280_write(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)
SPI write function for BME280.
int8_t ri_spi_bme280_read(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)
SPI Read function for BME280.
#define RD_SENSOR_DSP_LAST
Return last value from sensor. Parameter: No effect. Use default.
#define RD_SENSOR_ERR_NOT_SUPPORTED
Error code, given parameter is not supported by sensor.
bool rd_sensor_is_init(const rd_sensor_t *const sensor)
Check if given sensor structure is already initialized.
#define RD_SENSOR_CFG_SLEEP
Sensor should go to sleep immediately.
#define RD_SENSOR_CFG_MAX
Configure largest supported and implemented value.
#define RD_SENSOR_CFG_DEFAULT
Default value, always valid for the sensor.
void rd_sensor_uninitialize(rd_sensor_t *const p_sensor)
Mark sensor as uninitialized by calling the generic initialization. Will not clear the name of the se...
#define RD_SENSOR_DSP_OS
Oversample sensor values. Parameter: Number of samples.
rd_status_t rd_sensor_configuration_get(const rd_sensor_t *sensor, rd_sensor_configuration_t *config)
Implementation of ref rd_configuration_fp.
void rd_sensor_initialize(rd_sensor_t *const p_sensor)
Initialize sensor struct with non-null pointers which return RD_ERROR_NOT_INITIALIZED.
#define RD_SENSOR_DSP_LOW_PASS
Low pass sensor values Parameter: coefficient.
#define RD_SENSOR_ERR_INVALID
Error code, given parameter is invalid.
void rd_sensor_data_populate(rd_sensor_data_t *const target, const rd_sensor_data_t *const provided, const rd_sensor_data_fields_t requested)
Populate given target data with data provided by sensor as requested.
rd_status_t rd_sensor_configuration_set(const rd_sensor_t *sensor, rd_sensor_configuration_t *config)
Implementation of ref rd_configuration_fp.
#define RD_SENSOR_CFG_MIN
Configure smallest supported and implemented value.
#define RD_SENSOR_CFG_CONTINUOUS
Sensor will keep sampling at defined sample rate.
#define RD_SENSOR_CFG_NO_CHANGE
Do not change configured value.
rd_bus_t
Type of bus sensor uses.
uint64_t rd_sensor_timestamp_get(void)
Calls the timestamp function and returns its value.
#define RD_SENSOR_CFG_SINGLE
Sensor should go to sleep after single measurement.
Header to enable and disable module compilation.
Ruuvi error codes and error check function.
Ruuvi sensor interface Lifecycle: Beta
rd_status_t ri_bme280_uninit(rd_sensor_t *sensor, rd_bus_t bus, uint8_t handle)
rd_sensor_init_fp
#define BME280_SAMPLERATE_0_5MS
#define BME280_TEMPERATURE
#define BME280_SAMPLERATE_20MS
rd_status_t ri_bme280_samplerate_get(uint8_t *samplerate)
rd_sensor_setup_fp
#define BME280_SAMPLERATE_10MS
#define BME280_SAMPLERATE_1000MS
rd_status_t ri_bme280_dsp_set(uint8_t *dsp, uint8_t *parameter)
rd_sensor_dsp_fp
#define BME280_DSP_MODE_0
rd_status_t ri_bme280_mode_get(uint8_t *mode)
rd_sensor_setup_fp
rd_status_t ri_bme280_dsp_get(uint8_t *dsp, uint8_t *parameter)
rd_sensor_dsp_fp
#define BME280_MEAS_TIME_CONST3
rd_status_t ri_bme280_resolution_get(uint8_t *resolution)
rd_sensor_setup_fp
rd_status_t ri_bme280_resolution_set(uint8_t *resolution)
rd_sensor_setup_fp
#define BME280_SAMPLERATE_500MS
#define BME280_SAMPLERATE_125MS
rd_status_t ri_bme280_data_get(rd_sensor_data_t *const p_data)
rd_sensor_data_fp
#define BME280_DSP_MODE_2
#define BME280_SAMPLERATE_62_5MS
#define BME280_DSP_MODE_3
rd_status_t ri_bme280_scale_get(uint8_t *scale)
rd_sensor_setup_fp
rd_status_t ri_bme280_mode_set(uint8_t *mode)
rd_sensor_setup_fp
#define BME280_MEAS_TIME_CONST6
#define BME280_DSP_MODE_1
rd_status_t ri_bme280_scale_set(uint8_t *scale)
rd_sensor_setup_fp
#define BME280_DSP_MODE_4
rd_status_t ri_bme280_init(rd_sensor_t *p_sensor, rd_bus_t bus, uint8_t handle)
rd_sensor_init_fp
#define BME280_MEAS_TIME_CONST5
rd_status_t ri_bme280_samplerate_set(uint8_t *samplerate)
rd_sensor_setup_fp
#define BME280_MEAS_TIME_CONST1
#define BME280_HUMIDITY_MAX_VALUE
void bosch_delay_ms(uint32_t time_ms)
Implement delay in Bosch signature.
#define BME280_HUMIDITY_OFFSET
Generally, BMEs show 3% too little. Compensate.
Interface for I2C operations.
I2C read/write functions for Bosch BME280.
Interface for SPI operations.
SPI read/write functions for Bosch BME280.
rd_status_t ri_delay_ms(uint32_t time)
Delay a given number of milliseconds.
unsigned int humidity_rh
Relative humidity, %.
unsigned int temperature_c
Temperature, celcius.
unsigned int pressure_pa
Pressure, pascals.
Generic sensor data struct.
float * data
Data of sensor. Must contain as many elements as fields has bits set.
uint64_t timestamp_ms
Timestamp of the event, rd_sensor_timestamp_get.
rd_sensor_data_fields_t valid
Listing of valid data in this sample.
rd_sensor_data_fields_t fields
Description of datafields which may be contained in this sample.
Interface to sensor. Some sensors can implement additional functions. The additional functions are de...
rd_sensor_data_fp data_get
rd_sensor_data_fp
rd_configuration_fp configuration_set
rd_configuration_fp
rd_sensor_setup_fp samplerate_get
rd_sensor_setup_fp
rd_sensor_setup_fp resolution_get
rd_sensor_setup_fp
rd_sensor_init_fp uninit
rd_sensor_init_fp
rd_configuration_fp configuration_get
rd_configuration_fp
rd_sensor_dsp_fp dsp_get
rd_sensor_dsp_fp
rd_sensor_data_fields_t provides
Description of data fields the sensor is able to provide.
rd_sensor_dsp_fp dsp_set
rd_sensor_dsp_fp
rd_sensor_setup_fp mode_set
rd_sensor_setup_fp
const char * name
Sensor human-readable name. Should be at most 8 bytes long.
rd_sensor_setup_fp mode_get
rd_sensor_setup_fp
rd_sensor_setup_fp samplerate_set
rd_sensor_setup_fp
rd_sensor_init_fp init
rd_sensor_init_fp
rd_sensor_setup_fp scale_set
rd_sensor_setup_fp
rd_sensor_setup_fp resolution_set
rd_sensor_setup_fp
rd_sensor_setup_fp scale_get
rd_sensor_setup_fp
Union to access sensor data.
uint32_t bitfield
Bitfield used to access sensor data.
rd_sensor_data_bitfield_t datas
Structured data field.