diff --git a/Documentation/bluetooth/ess.rst b/Documentation/bluetooth/ess.rst new file mode 100644 index 0000000000000000000000000000000000000000..6a84a6aba07cdb58e34a084291562e4e8a89089b --- /dev/null +++ b/Documentation/bluetooth/ess.rst @@ -0,0 +1,65 @@ +Environmental Sensing Service +======================== + +.. warning:: + This service will be available in version v1.17 + +The Environmental Sensing Service (ESS) implements access to +the BME680 environmental sensor of the card10. + +It provides: + +- Temperature +- Relative humidity +- Pressure + + +If notifcations are enabled a measurement of all values is performed every 3 seconds. For each measurement a notification is sent for the characteristics which have notifications enabled. + + +A measurement can also be triggered by reading from a characteristic. A measurement takes roughly 200 ms. A notifciation will be sent to all characteristics which have notifications enabled except the one which was used to trigger the measurement. + + +BLE Service +----------- + +- Service + + UUID: ``181A`` + +- Temperature characteristic: + + UUID: ``2A6E`` + read and notify + +- Humidity characteristic: + + UUID: ``2A6F`` + read and notify + +- Pressure characteristic: + + UUID: ``2A6D`` + read and notify + +Temperature characteristic +--------------------------------- + +- 16 bit little endian value representing the measured temperature. + +- Unit: 0.01 deg C + + +Humidity characteristic +--------------------------------- + +- 16 bit little endian value representing the measured relative humidity. + +- Unit: 0.01% + +Pressure characteristic +--------------------------------- + +- 32 bit little endian value representing the measured pressure. + +- Unit: 0.1 Pa (0.001 hPa) diff --git a/Documentation/index.rst b/Documentation/index.rst index f83d9ee79b55cae3248cb1529be9cc1f02cda897..1090ad48cb9d2fce0e4cc5ed58512cd4b133c737 100644 --- a/Documentation/index.rst +++ b/Documentation/index.rst @@ -69,6 +69,7 @@ Last but not least, if you want to start hacking the lower-level firmware, the :maxdepth: 1 :caption: Bluetooth + bluetooth/ess bluetooth/file-transfer bluetooth/card10 bluetooth/nimble diff --git a/epicardium/ble/ble.c b/epicardium/ble/ble.c index b3e175f1dd1c6f5dea54b5d9bf2ae430c53386de..bfb33db010e1b66505a8fdabbfc78f1df269e9fe 100644 --- a/epicardium/ble/ble.c +++ b/epicardium/ble/ble.c @@ -69,6 +69,7 @@ extern void StackInit(void); extern void bleuart_init(void); extern void bleFileTransfer_init(void); extern void bleCard10_init(void); +extern void bleESS_init(void); extern void BbBleDrvSetTxPower(int8_t power); /*************************************************************************************************/ @@ -432,6 +433,7 @@ void vBleTask(void *pvParameters) bleuart_init(); bleFileTransfer_init(); bleCard10_init(); + bleESS_init(); lasttick = xTaskGetTickCount(); diff --git a/epicardium/ble/ble_api.h b/epicardium/ble/ble_api.h index d46b0fe8e63bd7017ea663a07f1d985cd9222be7..93261a58d1b8ac12dbd0091d70ea007d21af933f 100644 --- a/epicardium/ble/ble_api.h +++ b/epicardium/ble/ble_api.h @@ -22,7 +22,6 @@ /*************************************************************************************************/ void BleStart(void); - /* ATT client module interface. Used by main BLE module */ void bleValueUpdate(attEvt_t *pMsg); void bleDiscCback(dmConnId_t connId, uint8_t status); diff --git a/epicardium/ble/ble_main.c b/epicardium/ble/ble_main.c index a807a35731e7f16b1603b99bd43dd3fc3b71b468..431b4310a59cd2b811d1ec39670d8a08023423f4 100644 --- a/epicardium/ble/ble_main.c +++ b/epicardium/ble/ble_main.c @@ -40,6 +40,7 @@ #include "rscp/rscp_api.h" #include "profiles/gap_api.h" #include "cccd.h" +#include "ess.h" #include "ble_api.h" #include "epicardium.h" @@ -228,6 +229,9 @@ static const attsCccSet_t bleCccSet[BLE_NUM_CCC_IDX] = /* cccd handle value range security level */ {GATT_SC_CH_CCC_HDL, ATT_CLIENT_CFG_INDICATE, DM_SEC_LEVEL_NONE}, /* BLE_GATT_SC_CCC_IDX */ {BATT_LVL_CH_CCC_HDL, ATT_CLIENT_CFG_NOTIFY, DM_SEC_LEVEL_NONE}, /* BLE_BATT_LVL_CCC_IDX */ + {ESS_TEMP_CH_CCC_HDL, ATT_CLIENT_CFG_NOTIFY, DM_SEC_LEVEL_NONE}, /* BLE_ESS_TEMP_CCC_IDX */ + {ESS_HUMI_CH_CCC_HDL, ATT_CLIENT_CFG_NOTIFY, DM_SEC_LEVEL_NONE}, /* BLE_ESS_HUMI_CCC_IDX */ + {ESS_PRES_CH_CCC_HDL, ATT_CLIENT_CFG_NOTIFY, DM_SEC_LEVEL_NONE}, /* BLE_ESS_PRES_CCC_IDX */ }; /************************************************************************************************** @@ -436,18 +440,23 @@ static void bleProcCccState(bleMsg_t *pMsg) APP_TRACE_INFO3("ccc state ind value:%d handle:%d idx:%d", pMsg->ccc.value, pMsg->ccc.handle, pMsg->ccc.idx); /* handle battery level CCC */ - if (pMsg->ccc.idx == BLE_BATT_LVL_CCC_IDX) - { - if (pMsg->ccc.value == ATT_CLIENT_CFG_NOTIFY) - { - BasMeasBattStart((dmConnId_t) pMsg->ccc.hdr.param, BLE_BATT_TIMER_IND, BLE_BATT_LVL_CCC_IDX); - } - else - { - BasMeasBattStop((dmConnId_t) pMsg->ccc.hdr.param); - } - return; - } + switch(pMsg->ccc.idx) { + case BLE_BATT_LVL_CCC_IDX: + if (pMsg->ccc.value == ATT_CLIENT_CFG_NOTIFY) + { + BasMeasBattStart((dmConnId_t) pMsg->ccc.hdr.param, BLE_BATT_TIMER_IND, BLE_BATT_LVL_CCC_IDX); + } + else + { + BasMeasBattStop((dmConnId_t) pMsg->ccc.hdr.param); + } + break; + case BLE_ESS_TEMP_CCC_IDX: + case BLE_ESS_HUMI_CCC_IDX: + case BLE_ESS_PRES_CCC_IDX: + bleESS_ccc_update(); + break; + }; } /*************************************************************************************************/ @@ -463,6 +472,7 @@ static void bleClose(bleMsg_t *pMsg) { /* stop battery measurement */ BasMeasBattStop((dmConnId_t) pMsg->hdr.param); + bleESS_ccc_update(); GapClearDeviceName(); } @@ -760,6 +770,7 @@ static void bleProcMsg(bleMsg_t *pMsg) connOpen->peerAddr[3], connOpen->peerAddr[2], connOpen->peerAddr[1], connOpen->peerAddr[0]); BasProcMsg(&pMsg->hdr); + bleESS_ccc_update(); break; case DM_CONN_CLOSE_IND: diff --git a/epicardium/ble/cccd.h b/epicardium/ble/cccd.h index 02574bbdc9d0316eeff03ce3a1c19b1b0f09c94c..2715f6ebb6252e4995b73bb7980795b4c0354083 100644 --- a/epicardium/ble/cccd.h +++ b/epicardium/ble/cccd.h @@ -4,6 +4,9 @@ enum { BLE_GATT_SC_CCC_IDX, /*! GATT service, service changed characteristic */ BLE_BATT_LVL_CCC_IDX, /*! Battery service, battery level characteristic */ + BLE_ESS_TEMP_CCC_IDX, /*! Environmental sensing service, temperature characteristic */ + BLE_ESS_HUMI_CCC_IDX, /*! Environmental sensing service, humidity characteristic */ + BLE_ESS_PRES_CCC_IDX, /*! Environmental sensing service, pressure characteristic */ BLE_NUM_CCC_IDX }; diff --git a/epicardium/ble/ess.c b/epicardium/ble/ess.c new file mode 100644 index 0000000000000000000000000000000000000000..a4452e9d5d2a3685515f8bbaba9ad877f0978e64 --- /dev/null +++ b/epicardium/ble/ess.c @@ -0,0 +1,355 @@ +#include "ess.h" +#include "cccd.h" + +#include "wsf_types.h" +#include "util/bstream.h" +#include "wsf_assert.h" +#include "att_api.h" +#include "app_api.h" + +#include "epicardium.h" +#include "modules/log.h" +#include "modules/modules.h" + +#include "FreeRTOS.h" +#include "timers.h" + +#include <stdio.h> +#include <string.h> +#include <stdbool.h> +#include <machine/endian.h> + +/* clang-format off */ + +/* BLE UUID for ESS service*/ +static const uint8_t UUID_svc[] = { UINT16_TO_BYTES(ATT_UUID_ENVIRONMENTAL_SENSING_SERVICE) }; +static const uint16_t UUID_svc_len = sizeof(UUID_svc); + +/* BLE UUID for temperature */ +static const uint8_t UUID_char_temperature[] = { + ATT_PROP_READ | ATT_PROP_NOTIFY, + UINT16_TO_BYTES(ESS_TEMPERATURE_VAL_HDL), + UINT16_TO_BYTES(ATT_UUID_TEMPERATURE) +}; + +/* BLE UUID for humidity */ +static const uint8_t UUID_char_humidity[] = { + ATT_PROP_READ | ATT_PROP_NOTIFY, + UINT16_TO_BYTES(ESS_HUMIDITY_VAL_HDL), + UINT16_TO_BYTES(ATT_UUID_HUMIDITY) +}; + +/* BLE UUID for pressure */ +static const uint8_t UUID_char_pressure[] = { + ATT_PROP_READ | ATT_PROP_NOTIFY, + UINT16_TO_BYTES(ESS_PRESSURE_VAL_HDL), + UINT16_TO_BYTES(ATT_UUID_PRESSURE) +}; + +static const uint16_t UUID_char_len = sizeof(UUID_char_temperature); + +static uint8_t initTemperatureValue[] = { UINT16_TO_BYTES(0) }; +static uint16_t initTemperatureLen = sizeof(initTemperatureValue); + +static uint8_t initHumidityValue[] = { UINT16_TO_BYTES(0) }; +static uint16_t initHumidityLen = sizeof(initHumidityValue); + +static uint8_t initPressureValue[] = { UINT32_TO_BYTES(0) }; +static uint16_t initPressureLen = sizeof(initPressureValue); + +/* Temperature client characteristic configuration */ +static uint8_t essValTempChCcc[] = {UINT16_TO_BYTES(0x0000)}; +static const uint16_t essLenTempChCcc = sizeof(essValTempChCcc); + +/* Humidity client characteristic configuration */ +static uint8_t essValHumidityChCcc[] = {UINT16_TO_BYTES(0x0000)}; +static const uint16_t essLenHumidityChCcc = sizeof(essValHumidityChCcc); + +/* Pressure client characteristic configuration */ +static uint8_t essValPressureChCcc[] = {UINT16_TO_BYTES(0x0000)}; +static const uint16_t essLenPressureChCcc = sizeof(essValPressureChCcc); + +/* clang-format on */ + +/* + * BLE service description + */ + +static const attsAttr_t ESSSvcAttrList[] = { + { + .pUuid = attPrimSvcUuid, + .pValue = (uint8_t *)UUID_svc, + .pLen = (uint16_t *)&UUID_svc_len, + .maxLen = sizeof(UUID_svc), + .permissions = ATTS_PERMIT_READ, + }, + + // Temperature + { + .pUuid = attChUuid, + .pValue = (uint8_t *)UUID_char_temperature, + .pLen = (uint16_t *)&UUID_char_len, + .maxLen = sizeof(UUID_char_temperature), + .permissions = ATTS_PERMIT_READ, + }, + { + .pUuid = attTemperatureChUuid, + .pValue = initTemperatureValue, + .pLen = &initTemperatureLen, + .maxLen = sizeof(initTemperatureValue), + .settings = ATTS_SET_READ_CBACK, + .permissions = ATTS_PERMIT_READ | ATTS_PERMIT_READ_ENC | + ATTS_PERMIT_READ_AUTH, + }, + /* Characteristic CCC descriptor */ + { + .pUuid = attCliChCfgUuid, + .pValue = essValTempChCcc, + .pLen = (uint16_t *)&essLenTempChCcc, + .maxLen = sizeof(essValTempChCcc), + .settings = ATTS_SET_CCC, + .permissions = + (ATTS_PERMIT_READ | + ATTS_PERMIT_WRITE) // How about security? + }, + + // Humidity + { + .pUuid = attChUuid, + .pValue = (uint8_t *)UUID_char_humidity, + .pLen = (uint16_t *)&UUID_char_len, + .maxLen = sizeof(UUID_char_humidity), + .permissions = ATTS_PERMIT_READ, + }, + { + .pUuid = attHumidityChUuid, + .pValue = initHumidityValue, + .pLen = &initHumidityLen, + .maxLen = sizeof(initHumidityValue), + .settings = ATTS_SET_READ_CBACK, + .permissions = ATTS_PERMIT_READ | ATTS_PERMIT_READ_ENC | + ATTS_PERMIT_READ_AUTH, + }, + /* Characteristic CCC descriptor */ + { + .pUuid = attCliChCfgUuid, + .pValue = essValHumidityChCcc, + .pLen = (uint16_t *)&essLenHumidityChCcc, + .maxLen = sizeof(essValHumidityChCcc), + .settings = ATTS_SET_CCC, + .permissions = + (ATTS_PERMIT_READ | + ATTS_PERMIT_WRITE) // How about security? + }, + + // Pressure + { + .pUuid = attChUuid, + .pValue = (uint8_t *)UUID_char_pressure, + .pLen = (uint16_t *)&UUID_char_len, + .maxLen = sizeof(UUID_char_pressure), + .permissions = ATTS_PERMIT_READ, + }, + { + .pUuid = attPressureChUuid, + .pValue = initPressureValue, + .pLen = &initPressureLen, + .maxLen = sizeof(initPressureValue), + .settings = ATTS_SET_READ_CBACK, + .permissions = ATTS_PERMIT_READ | ATTS_PERMIT_READ_ENC | + ATTS_PERMIT_READ_AUTH, + }, + /* Characteristic CCC descriptor */ + { + .pUuid = attCliChCfgUuid, + .pValue = essValPressureChCcc, + .pLen = (uint16_t *)&essLenPressureChCcc, + .maxLen = sizeof(essValPressureChCcc), + .settings = ATTS_SET_CCC, + .permissions = + (ATTS_PERMIT_READ | + ATTS_PERMIT_WRITE) // How about security? + }, + +}; + +// validating that the service really has all charateristics +WSF_CT_ASSERT( + ((sizeof(ESSSvcAttrList) / sizeof(ESSSvcAttrList[0])) == + ESS_END_HDL - ESS_START_HDL + 1)); + +static TimerHandle_t poll_timer; +static StaticTimer_t poll_timer_buffer; +static void bleESS_update(struct bme680_sensor_data *data); + +static void workpoll(void *data) +{ + struct bme680_sensor_data sensor_data; + if (epic_bme680_read_sensors(&sensor_data) == 0) { + bleESS_update(&sensor_data); + } +} + +static void poll(TimerHandle_t xTimer) +{ + workqueue_schedule(workpoll, NULL); +} + +static void periodic(int period) +{ + if (poll_timer == NULL) { + poll_timer = xTimerCreateStatic( + "bme680_poll", + 1, + pdTRUE, + NULL, + poll, + &poll_timer_buffer + ); + } + + if (period < 1) { + xTimerStop(poll_timer, 0); + } else { + xTimerChangePeriod(poll_timer, pdMS_TO_TICKS(period), 0); + } +} + +static void +sendNotification(dmConnId_t connId, uint16_t handle, uint16_t cccidx) +{ + if (connId != DM_CONN_ID_NONE) { + uint16_t len; + uint8_t *value; + uint8_t ret = AttsGetAttr(handle, &len, &value); + if (ret == ATT_SUCCESS) { + if (AttsCccEnabled(connId, cccidx)) { + AttsHandleValueNtf(connId, handle, len, value); + } + } + } +} + +static void setAttrFromBME680(struct bme680_sensor_data *data) +{ + int16_t temperature; + uint16_t humidity; + uint32_t pressure; + + temperature = data->temperature * 100; + AttsSetAttr( + ESS_TEMPERATURE_VAL_HDL, + sizeof(temperature), + (uint8_t *)&temperature + ); + + humidity = data->humidity * 100; + AttsSetAttr( + ESS_HUMIDITY_VAL_HDL, sizeof(humidity), (uint8_t *)&humidity + ); + + pressure = data->pressure * 1000; + AttsSetAttr( + ESS_PRESSURE_VAL_HDL, sizeof(pressure), (uint8_t *)&pressure + ); +} + +/* + * BLE ESS read callback. + * + */ +static uint8_t readESSCB( + dmConnId_t connId, + uint16_t handle, + uint8_t operation, + uint16_t offset, + attsAttr_t *pAttr +) { + struct bme680_sensor_data data; + int ret = epic_bme680_read_sensors(&data); + if (ret != 0) { + return ATT_ERR_UNDEFINED; + } + setAttrFromBME680(&data); + + /* Send notifications (if enabled) for the _other_ characteristics. */ + switch (handle) { + case ESS_TEMPERATURE_VAL_HDL: + sendNotification( + connId, ESS_HUMIDITY_VAL_HDL, BLE_ESS_HUMI_CCC_IDX + ); + sendNotification( + connId, ESS_PRESSURE_VAL_HDL, BLE_ESS_PRES_CCC_IDX + ); + APP_TRACE_INFO1("ble-ess: read temperature: %d\n", temperature); + return ATT_SUCCESS; + case ESS_HUMIDITY_VAL_HDL: + sendNotification( + connId, ESS_TEMPERATURE_VAL_HDL, BLE_ESS_TEMP_CCC_IDX + ); + sendNotification( + connId, ESS_PRESSURE_VAL_HDL, BLE_ESS_PRES_CCC_IDX + ); + APP_TRACE_INFO1("ble-ess: read humidity: %u\n", humidity); + return ATT_SUCCESS; + case ESS_PRESSURE_VAL_HDL: + sendNotification( + connId, ESS_TEMPERATURE_VAL_HDL, BLE_ESS_TEMP_CCC_IDX + ); + sendNotification( + connId, ESS_HUMIDITY_VAL_HDL, BLE_ESS_HUMI_CCC_IDX + ); + APP_TRACE_INFO1("ble-ess: read pressure: %u\n", pressure); + return ATT_SUCCESS; + default: + APP_TRACE_INFO0("ble-card10: read no handler found\n"); + return ATT_ERR_HANDLE; + } +} + +static attsGroup_t svcESSGroup = { + .pNext = NULL, + .pAttr = (attsAttr_t *)ESSSvcAttrList, + .readCback = readESSCB, + .writeCback = NULL, + .startHandle = ESS_START_HDL, + .endHandle = ESS_END_HDL, +}; + +static void bleESS_update(struct bme680_sensor_data *data) +{ + setAttrFromBME680(data); + + /* Send notifications (if enabled) for all characteristics. */ + dmConnId_t connId = AppConnIsOpen(); + sendNotification(connId, ESS_TEMPERATURE_VAL_HDL, BLE_ESS_TEMP_CCC_IDX); + sendNotification(connId, ESS_HUMIDITY_VAL_HDL, BLE_ESS_HUMI_CCC_IDX); + sendNotification(connId, ESS_PRESSURE_VAL_HDL, BLE_ESS_PRES_CCC_IDX); +} + +/* + * This registers and starts the ESS service. + */ +void bleESS_init(void) +{ + AttsAddGroup(&svcESSGroup); +} + +/* + * Instruct the ESS service to check if any characterstics have + * notifications enabled and enable/disable periodic measurements. + */ +void bleESS_ccc_update(void) +{ + dmConnId_t connId = AppConnIsOpen(); + if (connId != DM_CONN_ID_NONE && + (AttsCccEnabled(connId, BLE_ESS_TEMP_CCC_IDX) || + AttsCccEnabled(connId, BLE_ESS_HUMI_CCC_IDX) || + AttsCccEnabled(connId, BLE_ESS_PRES_CCC_IDX))) { + LOG_INFO("ess", "enable periodic measurement"); + periodic(3000); + } else { + LOG_INFO("ess", "disable periodic measurement"); + periodic(0); + } +} diff --git a/epicardium/ble/ess.h b/epicardium/ble/ess.h new file mode 100644 index 0000000000000000000000000000000000000000..3f59edf8841eed21d6d57845c2a9d94f485e409d --- /dev/null +++ b/epicardium/ble/ess.h @@ -0,0 +1,31 @@ +#pragma once + +#include "epicardium.h" + +/*!< \brief Service start handle. */ +#define ESS_START_HDL 0x1000 +/*!< \brief Service end handle. */ +#define ESS_END_HDL (ESS_MAX_HDL - 1) + +enum { + /*!< \brief environmental sensing services service declaration */ + ESS_SVC_HDL = ESS_START_HDL, + /*!< \brief temperature characteristic */ + ESS_TEMPERATURE_CH_HDL, + ESS_TEMPERATURE_VAL_HDL, + ESS_TEMP_CH_CCC_HDL, /*!< Temperature CCCD */ + /*!< \brief humidity characteristic */ + ESS_HUMIDITY_CH_HDL, + ESS_HUMIDITY_VAL_HDL, + ESS_HUMI_CH_CCC_HDL, /*!< Humidity CCCD */ + /*!< \brief pressure characteristic */ + ESS_PRESSURE_CH_HDL, + ESS_PRESSURE_VAL_HDL, + ESS_PRES_CH_CCC_HDL, /*!< Pressure CCCD */ + + + /*!< \brief Maximum handle. */ + ESS_MAX_HDL +}; + +void bleESS_ccc_update(void); diff --git a/epicardium/ble/meson.build b/epicardium/ble/meson.build index 7da7925fc1a6c9a59d360881838f71a187bbea21..c2f10a12a8976cec3f049d9d8ca4617ef0cb70f9 100644 --- a/epicardium/ble/meson.build +++ b/epicardium/ble/meson.build @@ -10,5 +10,6 @@ ble_sources = files( 'bondings.c', 'uart.c', 'card10.c', + 'ess.c', 'filetransfer.c', ) diff --git a/epicardium/modules/bme680.c b/epicardium/modules/bme680.c index 8cda3a6e28d52a3dfa92aa33796ae91cb77f25d3..c92ca1abbb43ffcf04f8e82d18d01dd3d584a981 100644 --- a/epicardium/modules/bme680.c +++ b/epicardium/modules/bme680.c @@ -35,6 +35,34 @@ static int convert_error(int8_t error) } } +static int8_t +i2c_write(uint8_t addr, uint8_t reg, uint8_t *p_buf, uint16_t size) +{ + int8_t ret; + hwlock_acquire(HWLOCK_I2C); + ret = card10_bosch_i2c_write(addr, reg, p_buf, size); + hwlock_release(HWLOCK_I2C); + return ret; +} + +static int8_t i2c_read(uint8_t addr, uint8_t reg, uint8_t *p_buf, uint16_t size) +{ + int8_t ret; + hwlock_acquire(HWLOCK_I2C); + ret = card10_bosch_i2c_read(addr, reg, p_buf, size); + hwlock_release(HWLOCK_I2C); + return ret; +} + +static void delay(uint32_t msec) +{ + if (xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED) { + card10_bosch_delay(msec); + } else { + vTaskDelay(pdMS_TO_TICKS(msec)); + } +} + int epic_bme680_init() { int8_t result = BME680_OK; @@ -43,13 +71,11 @@ int epic_bme680_init() return 0; } - hwlock_acquire(HWLOCK_I2C); - 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; + bme.read = i2c_read; + bme.write = i2c_write; + bme.delay_ms = delay; /* * amb_temp can be set to 25 prior to configuring the gas sensor @@ -61,7 +87,7 @@ int epic_bme680_init() result = bme680_init(&bme); if (result != BME680_OK) { LOG_ERR("bme680", "bme680_init error: %d\n", result); - goto err; + return -convert_error(result); } /* @@ -74,7 +100,7 @@ int epic_bme680_init() 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; + bme.tph_sett.filter = BME680_FILTER_SIZE_0; /* Set the remaining gas sensor settings and link the heating profile */ bme.gas_sett.run_gas = BME680_ENABLE_GAS_MEAS; @@ -92,31 +118,33 @@ int epic_bme680_init() LOG_ERR("bme680", "bme680_set_sensor_settings error: %d\n", result); - goto err; + return -convert_error(result); } initialized = true; - result = BME680_OK; -err: - hwlock_release(HWLOCK_I2C); - return -convert_error(result); + return 0; } int epic_bme680_deinit() { + /* This is an intentional NO OP to keep the BME680 always initialized. + * + * If it configured to foreced mode, there is no energy consumption + * penalty. + */ + +#if 0 if (!initialized) { return 0; } - hwlock_acquire(HWLOCK_I2C); - 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; +#endif return 0; } @@ -129,30 +157,26 @@ int epic_bme680_read_sensors(struct bme680_sensor_data *data) return -EINVAL; } - hwlock_acquire(HWLOCK_I2C); - 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); - goto err; + return -convert_error(result); } /* * Wait for the measurement to complete. Release the I2C lock in the * meantime. */ - hwlock_release(HWLOCK_I2C); vTaskDelay(pdMS_TO_TICKS(profile_dur)); - hwlock_acquire(HWLOCK_I2C); 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); - goto err; + return -convert_error(result); } data->temperature = (float)raw_data.temperature / 100.0f; @@ -160,8 +184,5 @@ int epic_bme680_read_sensors(struct bme680_sensor_data *data) data->pressure = raw_data.pressure / 100.0f; data->gas_resistance = raw_data.gas_resistance; - result = BME680_OK; -err: - hwlock_release(HWLOCK_I2C); - return -convert_error(result); + return 0; } diff --git a/epicardium/modules/hardware.c b/epicardium/modules/hardware.c index a05c65f38af808b714de9158a71536c77452d482..fb413958ee0e090251e423e3661426c6fe3dfa85 100644 --- a/epicardium/modules/hardware.c +++ b/epicardium/modules/hardware.c @@ -194,6 +194,11 @@ int hardware_early_init(void) max86150_shut_down(); + /* + * BME680 Sensor + */ + epic_bme680_init(); + /* Allow user space to trigger interrupts. * Used for BLE, not sure if needed. */ SCB->CCR |= SCB_CCR_USERSETMPEND_Msk; @@ -276,11 +281,6 @@ int hardware_reset(void) */ epic_bhi160_disable_all_sensors(); - /* - * BME680 Sensor - */ - epic_bme680_deinit(); - epic_max30001_disable_sensor(); epic_max86150_disable_sensor(); diff --git a/epicardium/modules/modules.h b/epicardium/modules/modules.h index ccc8d0650497133bb193fc162fb112c6f364e82e..687d8db7c5b9408d4ba874cce8acdc3626edc510 100644 --- a/epicardium/modules/modules.h +++ b/epicardium/modules/modules.h @@ -120,6 +120,9 @@ void disp_forcelock(); #define BHI160_MUTEX_WAIT_MS 50 void vBhi160Task(void *pvParameters); +/* ---------- BME680 ------------------------------------------------------- */ +void bme680_periodic(int period); + /* ---------- MAX86150 ----------------------------------------------------- */ #define MAX86150_MUTEX_WAIT_MS 50 void vMAX86150Task(void *pvParameters); diff --git a/epicardium/modules/mutex.c b/epicardium/modules/mutex.c index 9d58eec080977d93f69f275350a5101a15d4a64b..4fa3eacf93e42a4ba1da5aaada9f660fb0f33b9c 100644 --- a/epicardium/modules/mutex.c +++ b/epicardium/modules/mutex.c @@ -23,6 +23,9 @@ void _mutex_create(struct mutex *m, const char *name) void mutex_lock(struct mutex *m) { + if (xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED) { + return; + } int ret = xSemaphoreTake(m->_rtos_mutex, portMAX_DELAY); /* Ensure locking was actually successful */ @@ -31,12 +34,18 @@ void mutex_lock(struct mutex *m) bool mutex_trylock(struct mutex *m) { + if (xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED) { + return true; + } int ret = xSemaphoreTake(m->_rtos_mutex, 0); return ret == pdTRUE; } void mutex_unlock(struct mutex *m) { + if (xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED) { + return; + } /* Ensure that only the owner can unlock a mutex */ assert(mutex_get_owner(m) == xTaskGetCurrentTaskHandle()); diff --git a/lib/sdk/Libraries/BTLE/stack/ble-host/include/att_uuid.h b/lib/sdk/Libraries/BTLE/stack/ble-host/include/att_uuid.h index b51cabdf90253bb654ac4bdb88ae4e6384a75752..a630a14911a880c6690187fe91ecb2dedefdbbaf 100644 --- a/lib/sdk/Libraries/BTLE/stack/ble-host/include/att_uuid.h +++ b/lib/sdk/Libraries/BTLE/stack/ble-host/include/att_uuid.h @@ -62,6 +62,7 @@ extern "C" { #define ATT_UUID_RUNNING_SPEED_SERVICE 0x1814 /*!< \brief Running Speed Service */ #define ATT_UUID_CYCLING_SPEED_SERVICE 0x1816 /*!< \brief Cycling Speed Service */ #define ATT_UUID_CYCLING_POWER_SERVICE 0x1818 /*!< \brief Cycling Power Service */ +#define ATT_UUID_ENVIRONMENTAL_SENSING_SERVICE 0x181A #define ATT_UUID_USER_DATA_SERVICE 0x181C /*!< \brief User Data Service */ #define ATT_UUID_WEIGHT_SCALE_SERVICE 0x181D /*!< \brief Weight Scale Service */ #define ATT_UUID_IP_SUPPORT_SERVICE 0x1820 /*!< \brief IP Support Service */ @@ -213,6 +214,9 @@ extern "C" { #define ATT_UUID_CTE_TX_DURATION 0x7F83 /*!< \brief Constant Tone Extension transmit duration */ #define ATT_UUID_CTE_INTERVAL 0x7F84 /*!< \brief Constant Tone Extension interval */ #define ATT_UUID_CTE_PHY 0x7F85 /*!< \brief Constant Tone Extension PHY */ +#define ATT_UUID_PRESSURE 0x2A6D +#define ATT_UUID_TEMPERATURE 0x2A6E +#define ATT_UUID_HUMIDITY 0x2A6F /**@}*/ /** \name GATT Unit UUIDs @@ -531,6 +535,9 @@ extern const uint8_t attCteTxCntChUuid[ATT_16_UUID_LEN]; /*!< \brief Constant To extern const uint8_t attCteTxDurChUuid[ATT_16_UUID_LEN]; /*!< \brief Constant Tone Extension transmit duration */ extern const uint8_t attCteIntChUuid[ATT_16_UUID_LEN]; /*!< \brief Constant Tone Extension interval */ extern const uint8_t attCtePhyChUuid[ATT_16_UUID_LEN]; /*!< \brief Constant Tone Extension PHY */ +extern const uint8_t attTemperatureChUuid[ATT_16_UUID_LEN]; +extern const uint8_t attHumidityChUuid[ATT_16_UUID_LEN]; +extern const uint8_t attPressureChUuid[ATT_16_UUID_LEN]; /**@}*/ /*! \} */ /* STACK_ATT_API */ diff --git a/lib/sdk/Libraries/BTLE/stack/ble-host/sources/stack/att/att_uuid.c b/lib/sdk/Libraries/BTLE/stack/ble-host/sources/stack/att/att_uuid.c index d34e556fd143446b2441590135eb2a2fd239ecee..53296d0b5c5a8be9a69449b0a1730bfd4f0a3734 100644 --- a/lib/sdk/Libraries/BTLE/stack/ble-host/sources/stack/att/att_uuid.c +++ b/lib/sdk/Libraries/BTLE/stack/ble-host/sources/stack/att/att_uuid.c @@ -186,3 +186,6 @@ const uint8_t attCteTxCntChUuid[ATT_16_UUID_LEN] = {UINT16_TO_BYTES(ATT_UUID_CTE const uint8_t attCteTxDurChUuid[ATT_16_UUID_LEN] = {UINT16_TO_BYTES(ATT_UUID_CTE_TX_DURATION)}; const uint8_t attCteIntChUuid[ATT_16_UUID_LEN] = {UINT16_TO_BYTES(ATT_UUID_CTE_INTERVAL)}; const uint8_t attCtePhyChUuid[ATT_16_UUID_LEN] = {UINT16_TO_BYTES(ATT_UUID_CTE_PHY)}; +const uint8_t attTemperatureChUuid[ATT_16_UUID_LEN] = {UINT16_TO_BYTES(ATT_UUID_TEMPERATURE)}; +const uint8_t attHumidityChUuid[ATT_16_UUID_LEN] = {UINT16_TO_BYTES(ATT_UUID_HUMIDITY)}; +const uint8_t attPressureChUuid[ATT_16_UUID_LEN] = {UINT16_TO_BYTES(ATT_UUID_PRESSURE)};