diff --git a/epicardium/modules/bme680.c b/epicardium/modules/bme680.c index bdc603d699fe5c4a63e8d29c0dfa79d6e810b66b..d70f9938e86f8b06371edb5ae14dd5b05aa050bd 100644 --- a/epicardium/modules/bme680.c +++ b/epicardium/modules/bme680.c @@ -1,14 +1,15 @@ -#include <stdbool.h> -#include <stddef.h> -#include <stdio.h> +#include "epicardium.h" +#include "modules/modules.h" +#include "modules/log.h" + +#include "card10.h" #include "bme680.h" #include "bosch.h" -#include "card10.h" -#include "epicardium.h" -#include "modules.h" -#include "modules/log.h" +#include <stdbool.h> +#include <stddef.h> +#include <stdio.h> #define HEATR_TEMP 320 #define HEATR_DUR 150 @@ -19,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: @@ -36,67 +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() { - int8_t result = BME680_OK; + if (!initialized) { + return 0; + } + + if (hwlock_acquire(HWLOCK_I2C, pdMS_TO_TICKS(100)) < 0) { + return -EBUSY; + } - result = bme680_soft_reset(&bme); + 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); } + hwlock_release(HWLOCK_I2C); initialized = false; return 0; } @@ -110,29 +133,43 @@ 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 = raw_data.temperature / 100.0l; - data->humidity = raw_data.humidity / 1000.0l; - data->pressure = raw_data.pressure / 100.0l; + data->temperature = (float)raw_data.temperature / 100.0f; + data->humidity = raw_data.humidity / 1000.0f; + 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); } diff --git a/pycardium/modules/bme680.c b/pycardium/modules/bme680.c index c9921cd7086b44d6c70168633755aa21a02014f6..ca4aca6d1dcb5d4f06c81ba20458f01bdafdb316 100644 --- a/pycardium/modules/bme680.c +++ b/pycardium/modules/bme680.c @@ -12,7 +12,7 @@ static mp_obj_t mp_bme680_init() mp_raise_OSError(-ret); } - return 0; + return mp_const_none; } static MP_DEFINE_CONST_FUN_OBJ_0(bme680_init_obj, mp_bme680_init); @@ -24,7 +24,7 @@ static mp_obj_t mp_bme680_deinit() mp_raise_OSError(-ret); } - return 0; + return mp_const_none; } static MP_DEFINE_CONST_FUN_OBJ_0(bme680_deinit_obj, mp_bme680_deinit);