!sensors/bme680: allow sensor configuration during registration

BREAKING CHANGE: bme680_register() takes an additional "*config" argument.
When config is NULL - driver behavior is the same as before.

With this change bme680 can be configured during registration in board logic.
This way we don't have to callibrate sensor from user-space but sensor is ready
to use after registration.

This change makes the registration the same as for bme688, which is a similar
sensor.

Signed-off-by: raiden00pl <raiden00@railab.me>
This commit is contained in:
raiden00pl 2025-05-07 11:32:53 +02:00 committed by Alan C. Assis
parent f3e62b837b
commit 2c606a7b41
3 changed files with 148 additions and 70 deletions

View file

@ -74,7 +74,7 @@ int board_bme680_initialize(int devno, int busno)
* available controllers.
*/
ret = bme680_register(devno, i2c);
ret = bme680_register(devno, i2c, NULL);
if (ret < 0)
{
snerr("ERROR: Error registering BME680 in I2C%d\n", busno);

View file

@ -402,6 +402,7 @@ static int bme680_calibrate(FAR struct sensor_lowerhalf_s *lower,
static int bme680_control(FAR struct sensor_lowerhalf_s *lower,
FAR struct file *filep,
int cmd, unsigned long arg);
/****************************************************************************
* Private Data
****************************************************************************/
@ -791,6 +792,10 @@ static int bme680_set_oversamp(FAR struct bme680_dev_s *priv)
}
#ifndef CONFIG_BME680_DISABLE_PRESS_MEAS
/****************************************************************************
* Name: bme680_push_press_data
****************************************************************************/
static int bme680_push_press_data(FAR struct bme680_dev_s *priv,
FAR struct bme680_data_s *data)
{
@ -815,6 +820,10 @@ static int bme680_push_press_data(FAR struct bme680_dev_s *priv,
return OK;
}
#else
/****************************************************************************
* Name: bme680_push_temp_data
****************************************************************************/
static int bme680_push_temp_data(FAR struct bme680_dev_s *priv,
FAR struct bme680_data_s *data)
{
@ -839,6 +848,10 @@ static int bme680_push_temp_data(FAR struct bme680_dev_s *priv,
#endif /* !CONFIG_BME680_DISABLE_PRESS_MEAS */
#ifndef CONFIG_BME680_DISABLE_HUM_MEAS
/****************************************************************************
* Name: bme680_push_hum_data
****************************************************************************/
static int bme680_push_hum_data(FAR struct bme680_dev_s *priv,
FAR struct bme680_data_s *data)
{
@ -863,6 +876,10 @@ static int bme680_push_hum_data(FAR struct bme680_dev_s *priv,
#endif /* !CONFIG_BME680_DISABLE_HUM_MEAS */
#ifndef CONFIG_BME680_DISABLE_GAS_MEAS
/****************************************************************************
* Name: bme680_push_gas_data
****************************************************************************/
static int bme680_push_gas_data(FAR struct bme680_dev_s *priv,
FAR struct bme680_data_s *data)
{
@ -965,6 +982,10 @@ static uint8_t calc_heater_dur(FAR const struct bme680_dev_s *priv)
return gas_wait_val;
}
/****************************************************************************
* Name: bme680_set_gas_config
****************************************************************************/
static int bme680_set_gas_config(FAR struct bme680_dev_s *priv)
{
int ret;
@ -1081,6 +1102,77 @@ err_out:
return ret;
}
/****************************************************************************
* Name: bme680_configure
****************************************************************************/
static int bme680_configure(FAR struct bme680_dev_s *priv,
FAR struct bme680_config_s *config)
{
int ret;
/* Sanity checks */
if (!CHECK_OS_BOUNDS(config->temp_os))
{
return -EINVAL;
}
#ifndef CONFIG_BME680_DISABLE_PRESS_MEAS
if (!CHECK_OS_BOUNDS(config->press_os))
{
return -EINVAL;
}
#endif
#ifndef CONFIG_BME680_DISABLE_HUM_MEAS
if (!CHECK_OS_BOUNDS(config->hum_os))
{
return -EINVAL;
}
#endif
#ifdef CONFIG_BME680_ENABLE_IIR_FILTER
if (config->filter_coef < BME680_FILTER_COEF0 ||
config->filter_coef > BME680_FILTER_COEF127)
{
return -EINVAL;
}
#endif
#ifndef CONFIG_BME680_DISABLE_GAS_MEAS
if (config->target_temp < MIN_HOT_PLATE_TEMP ||
config->target_temp > MAX_HOT_PLATE_TEMP)
{
return -EINVAL;
}
if (config->nb_conv > 9)
{
return -EINVAL;
}
#endif
/* Update config in priv */
memcpy(&priv->dev.config, config, sizeof(struct bme680_config_s));
ret = bme680_write_config(priv);
if (ret < 0)
{
snerr("Failed to calibrate sensor.\n");
return ret;
}
priv->dev.calibrated = true;
return ret;
}
/****************************************************************************
* Name: bme680_comp_temp
****************************************************************************/
static float bme680_comp_temp(FAR struct bme680_dev_s *priv,
uint32_t adc_temp)
{
@ -1107,6 +1199,10 @@ static float bme680_comp_temp(FAR struct bme680_dev_s *priv,
}
#ifndef CONFIG_BME680_DISABLE_PRESS_MEAS
/****************************************************************************
* Name: bme680_comp_press
****************************************************************************/
static float bme680_comp_press(FAR struct bme680_dev_s *priv,
uint32_t adc_press)
{
@ -1144,6 +1240,10 @@ static float bme680_comp_press(FAR struct bme680_dev_s *priv,
#endif /* !CONFIG_BME680_DISABLE_PRESS_MEAS */
#ifndef CONFIG_BME680_DISABLE_HUM_MEAS
/****************************************************************************
* Name: bme680_comp_hum
****************************************************************************/
static float bme680_comp_hum(FAR struct bme680_dev_s *priv,
uint16_t adc_hum)
{
@ -1187,6 +1287,10 @@ static float bme680_comp_hum(FAR struct bme680_dev_s *priv,
#endif /* !CONFIG_BME680_DISABLE_HUM_MEAS */
#ifndef CONFIG_BME680_DISABLE_GAS_MEAS
/****************************************************************************
* Name: bme680_calc_gas_res
****************************************************************************/
static float bme680_calc_gas_res(FAR struct bme680_dev_s *priv,
uint16_t adc_gas_res, uint8_t gas_range)
{
@ -1209,7 +1313,7 @@ static float bme680_calc_gas_res(FAR struct bme680_dev_s *priv,
*
* Description:
* Reads the raw data from the sensor and computes the compensated
* values, storing them in the data struct.
* values, storing them in the data struct.
*
****************************************************************************/
@ -1239,7 +1343,6 @@ static int bme680_read_measurements(FAR struct bme680_dev_s *priv,
uint8_t data_regs[BME680_DATA_LEN];
ret = bme680_getregs(priv, BME680_DATA_ADDR, data_regs, BME680_DATA_LEN);
if (ret < 0)
{
snerr("Failed to read data registers.\n");
@ -1285,7 +1388,6 @@ static int bme680_read_measurements(FAR struct bme680_dev_s *priv,
/* Is measured gas valid? */
gas_valid = data_regs[14] & BME680_GASM_VALID_MSK;
if (!gas_valid)
{
sninfo("Invalid gas measurement.\n");
@ -1293,7 +1395,6 @@ static int bme680_read_measurements(FAR struct bme680_dev_s *priv,
}
heat_stab = data_regs[14] & BME680_HEAT_STAB_MSK;
if (!heat_stab)
{
sninfo("The heater did not stabilize.\n");
@ -1313,7 +1414,7 @@ static int bme680_read_measurements(FAR struct bme680_dev_s *priv,
*
* Description:
* Compute the duration of a tphg cycle in us, taking into consideration
* the settings of the sensor.
* the settings of the sensor.
*
****************************************************************************/
@ -1362,6 +1463,10 @@ static uint16_t bme680_get_tphg_dur(FAR struct bme680_dev_s *priv)
return duration;
}
/****************************************************************************
* Name: bme680_activate
****************************************************************************/
static int bme680_activate(FAR struct sensor_lowerhalf_s *lower,
FAR struct file *filep, bool enable)
{
@ -1405,7 +1510,6 @@ static int bme680_activate(FAR struct sensor_lowerhalf_s *lower,
if (!priv->enabled && enable)
{
dev->calibrated = false;
priv->enabled = enable;
/* Wake up the polling thread */
@ -1420,6 +1524,10 @@ static int bme680_activate(FAR struct sensor_lowerhalf_s *lower,
return OK;
}
/****************************************************************************
* Name: bme680_calibrate
****************************************************************************/
static int bme680_calibrate(FAR struct sensor_lowerhalf_s *lower,
FAR struct file *filep, unsigned long arg)
{
@ -1427,7 +1535,6 @@ static int bme680_calibrate(FAR struct sensor_lowerhalf_s *lower,
FAR struct bme680_sensor_s *dev;
FAR struct bme680_dev_s *priv;
FAR struct bme680_config_s *calibval = (FAR struct bme680_config_s *)arg;
int ret;
/* Get offset inside array of lowerhalfs */
@ -1459,65 +1566,13 @@ static int bme680_calibrate(FAR struct sensor_lowerhalf_s *lower,
priv = container_of(dev, FAR struct bme680_dev_s, dev);
/* Sanity checks */
if (!CHECK_OS_BOUNDS(calibval->temp_os))
{
return -EINVAL;
}
#ifndef CONFIG_BME680_DISABLE_PRESS_MEAS
if (!CHECK_OS_BOUNDS(calibval->press_os))
{
return -EINVAL;
}
#endif
#ifndef CONFIG_BME680_DISABLE_HUM_MEAS
if (!CHECK_OS_BOUNDS(calibval->hum_os))
{
return -EINVAL;
}
#endif
#ifdef CONFIG_BME680_ENABLE_IIR_FILTER
if (calibval->filter_coef < BME680_FILTER_COEF0 ||
calibval->filter_coef > BME680_FILTER_COEF127)
{
return -EINVAL;
}
#endif
#ifndef CONFIG_BME680_DISABLE_GAS_MEAS
if (calibval->target_temp < MIN_HOT_PLATE_TEMP ||
calibval->target_temp > MAX_HOT_PLATE_TEMP)
{
return -EINVAL;
}
if (calibval->nb_conv > 9)
{
return -EINVAL;
}
#endif
/* Update config in priv */
memcpy(&priv->dev.config, calibval, sizeof(struct bme680_config_s));
ret = bme680_write_config(priv);
if (ret < 0)
{
snerr("Failed to calibrate sensor.\n");
return ret;
}
priv->dev.calibrated = true;
return ret;
return bme680_configure(priv, calibval);
}
/****************************************************************************
* Name: bme680_control
****************************************************************************/
static int bme680_control(FAR struct sensor_lowerhalf_s *lower,
FAR struct file *filep,
int cmd, unsigned long arg)
@ -1557,6 +1612,10 @@ static int bme680_control(FAR struct sensor_lowerhalf_s *lower,
return OK;
}
/****************************************************************************
* Name: bme680_thread
****************************************************************************/
static int bme680_thread(int argc, char **argv)
{
FAR struct bme680_dev_s *priv =
@ -1623,15 +1682,20 @@ static int bme680_thread(int argc, char **argv)
*
* Description:
* Register the BME680 character device
* @devno - The user-specified device number, starting from 0
* @i2c - An instance of the I2C interface to use to communicate with
*
* Input Parameters:
* devno - The user-specified device number, starting from 0
* i2c - An instance of the I2C interface to use to communicate with
* BME680
* config - optional sensor initial configuration
*
* Return value:
* Zero (OK) on success; a negated errno value on failure
*
****************************************************************************/
int bme680_register(int devno, FAR struct i2c_master_s *i2c)
int bme680_register(int devno, FAR struct i2c_master_s *i2c,
FAR struct bme680_config_s *config)
{
FAR struct sensor_lowerhalf_s *lower;
FAR struct bme680_dev_s *priv;
@ -1668,13 +1732,26 @@ int bme680_register(int devno, FAR struct i2c_master_s *i2c)
/* Get Calibration Data */
ret = bme680_get_calib_data(priv);
if (ret < 0)
{
snerr("Failed to read calib data from bme680:%d\n", ret);
goto err_init;
}
/* Sensor configuration */
priv->dev.calibrated = false;
if (config)
{
ret = bme680_configure(priv, config);
if (ret < 0)
{
snerr("Failed to configure bme680:%d\n", ret);
goto err_init;
}
}
#ifndef CONFIG_BME680_DISABLE_PRESS_MEAS
/* Register the barometer driver */

View file

@ -127,7 +127,8 @@ extern "C"
*
****************************************************************************/
int bme680_register(int devno, FAR struct i2c_master_s *i2c);
int bme680_register(int devno, FAR struct i2c_master_s *i2c,
FAR struct bme680_config_s *config);
#undef EXTERN
#ifdef __cplusplus