Skip to content
Snippets Groups Projects
Verified Commit 5e587a92 authored by rahix's avatar rahix
Browse files

fix(bme680): Lock I2C bus when accessing it


Signed-off-by: default avatarRahix <rahix@rahix.de>
parent 82b02fa1
No related branches found
No related tags found
No related merge requests found
......@@ -20,6 +20,8 @@ static struct bme680_dev bme;
static int convert_error(int8_t error)
{
switch (error) {
case BME680_OK:
return 0;
case BME680_E_NULL_PTR:
return EFAULT;
case BME680_E_COM_FAIL:
......@@ -37,74 +39,87 @@ int epic_bme680_init()
{
int8_t result = BME680_OK;
if (__builtin_expect(!initialized, 0)) {
bme.dev_id = BME680_I2C_ADDR_PRIMARY;
bme.intf = BME680_I2C_INTF;
bme.read = card10_bosch_i2c_read;
bme.write = card10_bosch_i2c_write;
bme.delay_ms = card10_bosch_delay;
/*
* amb_temp can be set to 25 prior to configuring the gas sensor
* or by performing a few temperature readings without operating
* the gas sensor.
*/
bme.amb_temp = 25;
result = bme680_init(&bme);
if (result != BME680_OK) {
LOG_ERR("bme680", "bme680_init error: %d\n", result);
return -convert_error(result);
}
/*
* Select the power mode. Must be set before writing the sensor
* configuration
*/
bme.power_mode = BME680_FORCED_MODE;
/* Set the temperature, pressure and humidity settings */
bme.tph_sett.os_hum = BME680_OS_2X;
bme.tph_sett.os_pres = BME680_OS_4X;
bme.tph_sett.os_temp = BME680_OS_8X;
bme.tph_sett.filter = BME680_FILTER_SIZE_3;
/* Set the remaining gas sensor settings and link the heating profile */
bme.gas_sett.run_gas = BME680_ENABLE_GAS_MEAS;
/* Create a ramp heat waveform in 3 steps */
bme.gas_sett.heatr_temp = HEATR_TEMP; /* degree Celsius */
bme.gas_sett.heatr_dur = HEATR_DUR; /* milliseconds */
/* Set the required sensor settings needed */
uint16_t settings_sel = BME680_OST_SEL | BME680_OSP_SEL |
BME680_OSH_SEL | BME680_FILTER_SEL |
BME680_GAS_SENSOR_SEL;
result = bme680_set_sensor_settings(settings_sel, &bme);
if (result != BME680_OK) {
LOG_ERR("bme680",
"bme680_set_sensor_settings error: %d\n",
result);
return -convert_error(result);
}
initialized = true;
if (initialized) {
return 0;
}
return 0;
if (hwlock_acquire(HWLOCK_I2C, pdMS_TO_TICKS(100)) < 0) {
return -EBUSY;
}
bme.dev_id = BME680_I2C_ADDR_PRIMARY;
bme.intf = BME680_I2C_INTF;
bme.read = card10_bosch_i2c_read;
bme.write = card10_bosch_i2c_write;
bme.delay_ms = card10_bosch_delay;
/*
* amb_temp can be set to 25 prior to configuring the gas sensor
* or by performing a few temperature readings without operating
* the gas sensor.
*/
bme.amb_temp = 25;
result = bme680_init(&bme);
if (result != BME680_OK) {
LOG_ERR("bme680", "bme680_init error: %d\n", result);
goto err;
}
/*
* Select the power mode. Must be set before writing the sensor
* configuration
*/
bme.power_mode = BME680_FORCED_MODE;
/* Set the temperature, pressure and humidity settings */
bme.tph_sett.os_hum = BME680_OS_2X;
bme.tph_sett.os_pres = BME680_OS_4X;
bme.tph_sett.os_temp = BME680_OS_8X;
bme.tph_sett.filter = BME680_FILTER_SIZE_3;
/* Set the remaining gas sensor settings and link the heating profile */
bme.gas_sett.run_gas = BME680_ENABLE_GAS_MEAS;
/* Create a ramp heat waveform in 3 steps */
bme.gas_sett.heatr_temp = HEATR_TEMP; /* degree Celsius */
bme.gas_sett.heatr_dur = HEATR_DUR; /* milliseconds */
/* Set the required sensor settings needed */
uint16_t settings_sel = BME680_OST_SEL | BME680_OSP_SEL |
BME680_OSH_SEL | BME680_FILTER_SEL |
BME680_GAS_SENSOR_SEL;
result = bme680_set_sensor_settings(settings_sel, &bme);
if (result != BME680_OK) {
LOG_ERR("bme680",
"bme680_set_sensor_settings error: %d\n",
result);
goto err;
}
initialized = true;
result = BME680_OK;
err:
hwlock_release(HWLOCK_I2C);
return -convert_error(result);
}
int epic_bme680_deinit()
{
if (initialized) {
int8_t result = bme680_soft_reset(&bme);
if (result != BME680_OK) {
LOG_ERR("bme680",
"bme680_soft_reset error: %d\n",
result);
return -convert_error(result);
}
if (!initialized) {
return 0;
}
if (hwlock_acquire(HWLOCK_I2C, pdMS_TO_TICKS(100)) < 0) {
return -EBUSY;
}
int8_t result = bme680_soft_reset(&bme);
if (result != BME680_OK) {
LOG_ERR("bme680", "bme680_soft_reset error: %d\n", result);
}
hwlock_release(HWLOCK_I2C);
initialized = false;
return 0;
}
......@@ -118,23 +133,34 @@ int epic_bme680_read_sensors(struct bme680_sensor_data *data)
return -EINVAL;
}
if (hwlock_acquire(HWLOCK_I2C, pdMS_TO_TICKS(100)) < 0) {
return -EBUSY;
}
uint16_t profile_dur = 0;
bme680_get_profile_dur(&profile_dur, &bme);
result = bme680_set_sensor_mode(&bme); /* Trigger a measurement */
if (result != BME680_OK) {
LOG_ERR("bme680", "bme680_set_sensor_mode error: %d\n", result);
return -convert_error(result);
goto err;
}
vTaskDelay(pdMS_TO_TICKS(
profile_dur)); /* Wait for the measurement to complete */
/*
* Wait for the measurement to complete. Release the I2C lock in the
* meantime.
*/
hwlock_release(HWLOCK_I2C);
vTaskDelay(pdMS_TO_TICKS(profile_dur));
if (hwlock_acquire(HWLOCK_I2C, pdMS_TO_TICKS(100)) < 0) {
return -EBUSY;
}
struct bme680_field_data raw_data;
result = bme680_get_sensor_data(&raw_data, &bme);
if (result != BME680_OK) {
LOG_ERR("bme680", "bme680_get_sensor_data error: %d\n", result);
return -convert_error(result);
goto err;
}
data->temperature = (float)raw_data.temperature / 100.0f;
......@@ -142,5 +168,8 @@ int epic_bme680_read_sensors(struct bme680_sensor_data *data)
data->pressure = raw_data.pressure / 100.0f;
data->gas_resistance = raw_data.gas_resistance;
return 0;
result = BME680_OK;
err:
hwlock_release(HWLOCK_I2C);
return -convert_error(result);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment