Hackster is hosting Hackster Holidays, Ep. 7: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Friday!Stream Hackster Holidays, Ep. 7 on Friday!
Cris ThomasJiss Joseph Thomas
Created January 31, 2020 © GPL3+

Smart Module for Healthcare and Asset Monitoring

An RSL10-SENSE based smart module for Healthcare and Asset Monitoring

IntermediateFull instructions provided20 hours207

Things used in this project

Hardware components

RSL10-SENSE-GEVK
onsemi RSL10-SENSE-GEVK
×1
Connector Accessory, Band Strap
Connector Accessory, Band Strap
×1
JLink Debugger
Provided with the kit
×1
Micro-USB to USB Cable (Generic)
Micro-USB to USB Cable (Generic)
×1
Coin Cell Battery CR2032
Coin Cell Battery CR2032
×1

Software apps and online services

Atmosphere IoT Platform
Atmosphere IoT agent
SEGGER JLink Software

Story

Read more

Schematics

End Product

Version 1

Code

Smart Module

JavaScript
Version 1
{
  "name": "SmartBand",
  "createVersion": "2017-08-12",
  "description": "New Project",
  "lastModified": "2020-03-11T23:12:22.070Z",
  "created": "2020-03-11T23:12:22.070Z",
  "meta": {
    "projectTypeName": "RSL10-SENSE-GEVK",
    "projectTypeId": "RSL10-SENSE-GEVK"
  },
  "planes": {
    "RSL10-SENSE-GEVK": {
      "type": "OnSemi",
      "compilerVersion": "latest",
      "variants": [
        "RSL10",
        "RSL10-SENSE-GEVK"
      ],
      "meta": {},
      "elements": [
        {
          "name": "Interval",
          "type": "EmbeddedInterval",
          "variants": [
            "embedded",
            "triggers",
            "abilities",
            "properties",
            "variables"
          ],
          "properties": {
            "errorData": {},
            "code": {
              "trigger": "\treturn ATMO_Status_Success;",
              "setup": "\n\tATMO_INTERVAL_Handle_t intervalHandle;\n    ATMO_INTERVAL_AddAbilityInterval(\n\t\tATMO_PROPERTY(Interval, instance), \n\t\tATMO_ABILITY(Interval, interval), \n\t\tATMO_PROPERTY(Interval, time), \n\t\t&intervalHandle\n\t);\n\t\n\treturn ATMO_Status_Success;\n\t",
              "interval": "\treturn ATMO_Status_Success;"
            },
            "variables": {},
            "embeddedPropertyConversions": {},
            "codeUserChanged": {
              "setup": false,
              "interval": false
            },
            "instance": "ATMO_DRIVERINSTANCE_INTERVAL_INTERVAL1",
            "time": 1000
          },
          "meta": {
            "editorX": 38,
            "editorY": 388,
            "lastTrigger": "interval"
          },
          "triggers": {
            "triggered": [],
            "interval": [
              {
                "mapping": {},
                "targetOrder": [],
                "targetElement": "BME680",
                "targetAbility": "readTemperature"
              }
            ]
          },
          "interruptAbilities": {
            "trigger": false,
            "setup": false,
            "interval": true
          },
          "abilities": [
            {
              "name": "trigger",
              "triggers": [
                "triggered"
              ]
            },
            {
              "name": "setup",
              "triggers": []
            },
            {
              "name": "interval",
              "triggers": [
                "interval"
              ]
            }
          ]
        },
        {
          "name": "BME680",
          "type": "EmbeddedBME680",
          "variants": [
            "embedded",
            "triggers",
            "abilities",
            "properties",
            "variables"
          ],
          "properties": {
            "errorData": {},
            "code": {
              "trigger": "\treturn ATMO_Status_Success;",
              "setup": "BME680_Config_t config;\nconfig.i2cInstance = ATMO_PROPERTY(BME680, i2cInstance );\nconfig.i2cAddr = ATMO_PROPERTY(BME680, i2cAddress );\n\nif ( !BME680_Init( &config ) )\n{\n\treturn ATMO_Status_Fail;\n}\n\nreturn ATMO_Status_Success;",
              "readTemperature": "float temperature = 0.0;\n\nif ( BME680_GetTempData( &temperature ) != BME680_Status_Success )\n{\n\treturn ATMO_Status_Fail;\n}\n\nATMO_CreateValueFloat( out, temperature );\n\nreturn ATMO_Status_Success;",
              "readHumidity": "float humidity = 0.0;\n\nif ( BME680_GetHumidity( &humidity ) != BME680_Status_Success )\n{\n\treturn ATMO_Status_Fail;\n}\n\nATMO_CreateValueFloat( out, humidity );\n\nreturn ATMO_Status_Success;",
              "readPressure": "float pressure = 0.0;\n\nif ( BME680_GetPressure( &pressure ) != BME680_Status_Success )\n{\n\treturn ATMO_Status_Fail;\n}\n\nATMO_CreateValueFloat( out, pressure );\n\nreturn ATMO_Status_Success;",
              "readGasResistance": "float gas_resistance = 0.0;\n\nif ( BME680_GetGasRes( &gas_resistance ) != BME680_Status_Success )\n{\n\treturn ATMO_Status_Fail;\n}\n\nATMO_CreateValueFloat( out, gas_resistance );\n\nreturn ATMO_Status_Success;"
            },
            "variables": {},
            "embeddedPropertyConversions": {},
            "codeUserChanged": {
              "setup": false,
              "readTemperature": false,
              "readHumidity": false,
              "readPressure": false,
              "readGasResistance": false
            },
            "i2cInstance": "ATMO_DRIVERINSTANCE_I2C_I2C1",
            "i2cAddress": "0x76"
          },
          "meta": {
            "editorX": 212,
            "editorY": 386,
            "lastTrigger": "humidityRead"
          },
          "triggers": {
            "triggered": [],
            "temperatureRead": [
              {
                "mapping": {},
                "targetOrder": [],
                "targetElement": "BLE_Write_Temp",
                "targetAbility": "setValue"
              }
            ],
            "humidityRead": [
              {
                "mapping": {},
                "targetOrder": [],
                "targetElement": "BLE_Write_Humi",
                "targetAbility": "setValue"
              }
            ],
            "pressureRead": [
              {
                "mapping": {},
                "targetOrder": [],
                "targetElement": "BLE_Write_Pres",
                "targetAbility": "setValue"
              }
            ],
            "gasResistanceRead": []
          },
          "interruptAbilities": {
            "trigger": false,
            "setup": false,
            "readTemperature": false,
            "readHumidity": false,
            "readPressure": false,
            "readGasResistance": false
          },
          "abilities": [
            {
              "name": "trigger",
              "triggers": [
                "triggered"
              ]
            },
            {
              "name": "setup",
              "triggers": []
            },
            {
              "name": "readTemperature",
              "triggers": [
                "temperatureRead"
              ]
            },
            {
              "name": "readHumidity",
              "triggers": [
                "humidityRead"
              ]
            },
            {
              "name": "readPressure",
              "triggers": [
                "pressureRead"
              ]
            },
            {
              "name": "readGasResistance",
              "triggers": [
                "gasResistanceRead"
              ]
            }
          ]
        },
        {
          "name": "NOA1305AmbientLight",
          "type": "EmbeddedNOA1305",
          "variants": [
            "embedded",
            "triggers",
            "abilities",
            "properties",
            "variables"
          ],
          "properties": {
            "errorData": {},
            "code": {
              "trigger": "\treturn ATMO_Status_Success;",
              "setup": "    if(!NOA1305_Init(ATMO_PROPERTY(NOA1305AmbientLight, i2cInstance)))\n    {\n        return ATMO_Status_Fail;\n    }\n\n    return ATMO_Status_Success;",
              "readAmbientLight": "    uint32_t ambientLightLux = 0;\n    if(!NOA1305_GetAmbientLight(&ambientLightLux))\n    {\n        return ATMO_Status_Fail;\n    }\n    ATMO_CreateValueUnsignedInt(out, ambientLightLux);\n    return ATMO_Status_Success;"
            },
            "variables": {},
            "embeddedPropertyConversions": {},
            "codeUserChanged": {
              "setup": false,
              "readAmbientLight": false
            },
            "i2cInstance": "ATMO_DRIVERINSTANCE_I2C_I2C1"
          },
          "meta": {
            "editorX": 24,
            "editorY": 3,
            "lastTrigger": "ambientLightRead"
          },
          "triggers": {
            "triggered": [],
            "ambientLightRead": []
          },
          "interruptAbilities": {
            "trigger": false,
            "setup": false,
            "readAmbientLight": false
          },
          "abilities": [
            {
              "name": "trigger",
              "triggers": [
                "triggered"
              ]
            },
            {
              "name": "setup",
              "triggers": []
            },
            {
              "name": "readAmbientLight",
              "triggers": [
                "ambientLightRead"
              ]
            }
          ]
        },
        {
          "name": "EmbeddedBHI160",
          "type": "EmbeddedBHI160",
          "variants": [
            "embedded",
            "triggers",
            "abilities",
            "properties",
            "variables"
          ],
          "properties": {
            "errorData": {},
            "code": {
              "trigger": "\treturn ATMO_Status_Success;",
              "setup": "    BHI160_Config_t config;\n    config.i2cInstance = ATMO_PROPERTY(EmbeddedBHI160, i2cInstance);\n    config.gpioInstance = ATMO_PROPERTY(EmbeddedBHI160, gpioInstance);\n    config.intPin = ATMO_PROPERTY(EmbeddedBHI160, intPin);\n\n    if(!BHI160_Init(&config))\n    {\n        return ATMO_Status_Fail;\n    }\n    return ATMO_Status_Success;",
              "xAcceleration": "    ATMO_3dFloatVector_t data;\n    BHI160_GetData(&data, NULL, NULL);\n    ATMO_CreateValueFloat(out, data.x);\n    return ATMO_Status_Success;",
              "yAcceleration": "    ATMO_3dFloatVector_t data;\n    BHI160_GetData(&data, NULL, NULL);\n    ATMO_CreateValueFloat(out, data.y);\n    return ATMO_Status_Success;",
              "zAcceleration": "    ATMO_3dFloatVector_t data;\n    BHI160_GetData(&data, NULL, NULL);\n    ATMO_CreateValueFloat(out, data.z);\n    return ATMO_Status_Success;",
              "acceleration": "    ATMO_3dFloatVector_t data;\n    BHI160_GetData(&data, NULL, NULL);\n    ATMO_CreateValue3dVectorFloat(out, &data);\n    return ATMO_Status_Success;",
              "angularRate": "    ATMO_3dFloatVector_t data;\n    BHI160_GetData(NULL, &data, NULL);\n    ATMO_CreateValue3dVectorFloat(out, &data);\n    return ATMO_Status_Success;",
              "xAngularRate": "    ATMO_3dFloatVector_t data;\n    BHI160_GetData(NULL, &data, NULL);\n    ATMO_CreateValueFloat(out, data.x);\n    return ATMO_Status_Success;",
              "yAngularRate": "    ATMO_3dFloatVector_t data;\n    BHI160_GetData(NULL, &data, NULL);\n    ATMO_CreateValueFloat(out, data.y);\n    return ATMO_Status_Success;",
              "zAngularRate": "    ATMO_3dFloatVector_t data;\n    BHI160_GetData(NULL, &data, NULL);\n    ATMO_CreateValueFloat(out, data.z);\n    return ATMO_Status_Success;",
              "orientation": "    ATMO_3dFloatVector_t data;\n    BHI160_GetData(NULL, NULL, &data);\n    ATMO_CreateValue3dVectorFloat(out, &data);\n    return ATMO_Status_Success;",
              "xOrientation": "    ATMO_3dFloatVector_t data;\n    BHI160_GetData(NULL, NULL, &data);\n    ATMO_CreateValueFloat(out, data.x);\n    return ATMO_Status_Success;",
              "yOrientation": "    ATMO_3dFloatVector_t data;\n    BHI160_GetData(NULL, NULL, &data);\n    ATMO_CreateValueFloat(out, data.y);\n    return ATMO_Status_Success;",
              "zOrientation": "    ATMO_3dFloatVector_t data;\n    BHI160_GetData(NULL, NULL, &data);\n    ATMO_CreateValueFloat(out, data.z);\n    return ATMO_Status_Success;"
            },
            "variables": {},
            "embeddedPropertyConversions": {},
            "codeUserChanged": {
              "setup": false,
              "xAcceleration": false,
              "yAcceleration": false,
              "zAcceleration": false,
              "acceleration": false,
              "angularRate": false,
              "xAngularRate": false,
              "yAngularRate": false,
              "zAngularRate": false,
              "orientation": false,
              "xOrientation": false,
              "yOrientation": false,
              "zOrientation": false
            },
            "i2cInstance": "ATMO_DRIVERINSTANCE_I2C_I2C1",
            "gpioInstance": "ATMO_DRIVERINSTANCE_GPIO_GPIO1",
            "intPin": 9
          },
          "meta": {
            "editorX": 129,
            "editorY": 3,
            "lastTrigger": "xAccelerationRead"
          },
          "triggers": {
            "triggered": [],
            "xAccelerationRead": [],
            "yAccelerationRead": [],
            "zAccelerationRead": [],
            "accelerationRead": [],
            "angularRateRead": [],
            "xAngularRateRead": [],
            "yAngularRateRead": [],
            "zAngularRateRead": [],
            "orientationRead": [],
            "xOrientationRead": [],
            "yOrientationRead": [],
            "zOrientationRead": []
          },
          "interruptAbilities": {
            "trigger": false,
            "setup": false,
            "xAcceleration": false,
            "yAcceleration": false,
            "zAcceleration": false,
            "acceleration": false,
            "angularRate": false,
            "xAngularRate": false,
            "yAngularRate": false,
            "zAngularRate": false,
            "orientation": false,
            "xOrientation": false,
            "yOrientation": false,
            "zOrientation": false
          },
          "abilities": [
            {
              "name": "trigger",
              "triggers": [
                "triggered"
              ]
            },
            {
              "name": "setup",
              "triggers": []
            },
            {
              "name": "xAcceleration",
              "triggers": [
                "xAccelerationRead"
              ]
            },
            {
              "name": "yAcceleration",
              "triggers": [
                "yAccelerationRead"
              ]
            },
            {
              "name": "zAcceleration",
              "triggers": [
                "zAccelerationRead"
              ]
            },
            {
              "name": "acceleration",
              "triggers": [
                "accelerationRead"
              ]
            },
            {
              "name": "angularRate",
              "triggers": [
                "angularRateRead"
              ]
            },
            {
              "name": "xAngularRate",
              "triggers": [
                "xAngularRateRead"
              ]
            },
            {
              "name": "yAngularRate",
              "triggers": [
                "yAngularRateRead"
              ]
            },
            {
              "name": "zAngularRate",
              "triggers": [
                "zAngularRateRead"
              ]
            },
            {
              "name": "orientation",
              "triggers": [
                "orientationRead"
              ]
            },
            {
              "name": "xOrientation",
              "triggers": [
                "xOrientationRead"
              ]
            },
            {
              "name": "yOrientation",
              "triggers": [
                "yOrientationRead"
              ]
            },
            {
              "name": "zOrientation",
              "triggers": [
                "zOrientationRead"
              ]
            }
          ]
        },
        {
          "name": "BLE_Write_Temp",
          "type": "EmbeddedBLECharacteristicCustom",
          "variants": [
            "embedded",
            "triggers",
            "abilities",
            "properties",
            "variables",
            "ble"
          ],
          "properties": {
            "errorData": {},
            "code": {
              "trigger": "\treturn ATMO_Status_Success;",
              "setup": "\n\tATMO_BLE_GATTSAddService(\n\t\tATMO_PROPERTY(BLE_Write_Temp, instance),\n\t\t&ATMO_VARIABLE(BLE_Write_Temp, bleServiceHandle), \n\t\tATMO_PROPERTY(BLE_Write_Temp, bleServiceUuid));\n\t\n\tuint8_t property = 0;\n\tuint8_t permission = 0;\n\t\n\tproperty |= ATMO_PROPERTY(BLE_Write_Temp, read) ? ATMO_BLE_Property_Read : 0;\n\tproperty |= ATMO_PROPERTY(BLE_Write_Temp, write) ? ATMO_BLE_Property_Write : 0;\n\tproperty |= ATMO_PROPERTY(BLE_Write_Temp, notify) ? ATMO_BLE_Property_Notify : 0;\n\n\tpermission |= ATMO_PROPERTY(BLE_Write_Temp, read) ? ATMO_BLE_Permission_Read : 0;\n\tpermission |= ATMO_PROPERTY(BLE_Write_Temp, write) ? ATMO_BLE_Permission_Write : 0;\n\n\tATMO_DATATYPE types[3] = {ATMO_PROPERTY(BLE_Write_Temp, writeDataType), ATMO_PROPERTY(BLE_Write_Temp, readDataType), ATMO_PROPERTY(BLE_Write_Temp, notifyDataType)};\n\t\n\tATMO_BLE_GATTSAddCharacteristic(\n\t\tATMO_PROPERTY(BLE_Write_Temp, instance),\n\t\t&ATMO_VARIABLE(BLE_Write_Temp, bleCharacteristicHandle), \n\t\tATMO_VARIABLE(BLE_Write_Temp, bleServiceHandle), \n\t\tATMO_PROPERTY(BLE_Write_Temp, bleCharacteristicUuid), \n\t\tproperty, permission, ATMO_GetMaxValueSize(3, 64, types));\n\t\n\tATMO_BLE_GATTSRegisterCharacteristicAbilityHandle(\n\t\tATMO_PROPERTY(BLE_Write_Temp, instance),\n\t\tATMO_VARIABLE(BLE_Write_Temp, bleCharacteristicHandle), \n\t\tATMO_BLE_Characteristic_Written, \n\t\tATMO_ABILITY(BLE_Write_Temp, written));\n\t\n\treturn ATMO_Status_Success;\n\t",
              "setValue": "\n\t\n\t// Convert to the desired write data type\n\tATMO_Value_t convertedValue;\n\tATMO_InitValue(&convertedValue);\n\tATMO_CreateValueConverted(&convertedValue, ATMO_PROPERTY(BLE_Write_Temp, readDataType), in);\n\n\tATMO_BLE_GATTSSetCharacteristic(\n\t\tATMO_PROPERTY(BLE_Write_Temp, instance),\n\t\tATMO_VARIABLE(BLE_Write_Temp, bleCharacteristicHandle),\n\t\tconvertedValue.size, \n\t\t(uint8_t *)convertedValue.data,\n\t\tNULL);\n\t\n\tATMO_FreeValue(&convertedValue);\n\t\t\n\treturn ATMO_Status_Success;\n\t",
              "written": "\n\tATMO_CreateValueConverted(out, ATMO_PROPERTY(BLE_Write_Temp, writeDataType), in);\n\treturn ATMO_Status_Success;\n\t",
              "subscibed": "\treturn ATMO_Status_Success;",
              "unsubscribed": "\treturn ATMO_Status_Success;"
            },
            "variables": {
              "bleServiceHandle": {
                "type": "ATMO_BLE_Handle_t"
              },
              "bleCharacteristicHandle": {
                "type": "ATMO_BLE_Handle_t"
              }
            },
            "embeddedPropertyConversions": {
              "bleServiceUuid": "string",
              "bleCharacteristicUuid": "string"
            },
            "codeUserChanged": {
              "setup": false,
              "setValue": false,
              "written": false,
              "subscibed": false,
              "unsubscribed": false
            },
            "instance": "ATMO_DRIVERINSTANCE_BLE_BLE1",
            "bleServiceUuid": "dbc7024c-dede-49a1-8dd8-43238503ba65",
            "bleCharacteristicUuid": "dbc7024c-dede-49a1-8dd8-43238503ba66",
            "read": true,
            "write": true,
            "notify": false,
            "readDataType": "ATMO_DATATYPE_FLOAT",
            "writeDataType": "ATMO_DATATYPE_FLOAT",
            "notifyDataType": "ATMO_DATATYPE_STRING"
          },
          "meta": {
            "editorX": 395,
            "editorY": 281,
            "lastTrigger": "written"
          },
          "triggers": {
            "triggered": [],
            "written": [],
            "subscibed": [],
            "unsubscribed": []
          },
          "interruptAbilities": {
            "trigger": false,
            "setup": false,
            "setValue": "valueSet",
            "written": false,
            "subscibed": false,
            "unsubscribed": false
          },
          "abilities": [
            {
              "name": "trigger",
              "triggers": [
                "triggered"
              ]
            },
            {
              "name": "setup",
              "triggers": []
            },
            {
              "name": "setValue",
              "triggers": []
            },
            {
              "name": "written",
              "triggers": [
                "written"
              ]
            },
            {
              "name": "subscibed",
              "triggers": [
                "subscibed"
              ]
            },
            {
              "name": "unsubscribed",
              "triggers": [
                "unsubscribed"
              ]
            }
          ]
        },
        {
          "name": "BLE_Write_Pres",
          "type": "EmbeddedBLECharacteristicCustom",
          "variants": [
            "embedded",
            "triggers",
            "abilities",
            "properties",
            "variables",
            "ble"
          ],
          "properties": {
            "errorData": {},
            "code": {
              "trigger": "\treturn ATMO_Status_Success;",
              "setup": "\n\tATMO_BLE_GATTSAddService(\n\t\tATMO_PROPERTY(BLE_Write_Pres, instance),\n\t\t&ATMO_VARIABLE(BLE_Write_Pres, bleServiceHandle), \n\t\tATMO_PROPERTY(BLE_Write_Pres, bleServiceUuid));\n\t\n\tuint8_t property = 0;\n\tuint8_t permission = 0;\n\t\n\tproperty |= ATMO_PROPERTY(BLE_Write_Pres, read) ? ATMO_BLE_Property_Read : 0;\n\tproperty |= ATMO_PROPERTY(BLE_Write_Pres, write) ? ATMO_BLE_Property_Write : 0;\n\tproperty |= ATMO_PROPERTY(BLE_Write_Pres, notify) ? ATMO_BLE_Property_Notify : 0;\n\n\tpermission |= ATMO_PROPERTY(BLE_Write_Pres, read) ? ATMO_BLE_Permission_Read : 0;\n\tpermission |= ATMO_PROPERTY(BLE_Write_Pres, write) ? ATMO_BLE_Permission_Write : 0;\n\n\tATMO_DATATYPE types[3] = {ATMO_PROPERTY(BLE_Write_Pres, writeDataType), ATMO_PROPERTY(BLE_Write_Pres, readDataType), ATMO_PROPERTY(BLE_Write_Pres, notifyDataType)};\n\t\n\tATMO_BLE_GATTSAddCharacteristic(\n\t\tATMO_PROPERTY(BLE_Write_Pres, instance),\n\t\t&ATMO_VARIABLE(BLE_Write_Pres, bleCharacteristicHandle), \n\t\tATMO_VARIABLE(BLE_Write_Pres, bleServiceHandle), \n\t\tATMO_PROPERTY(BLE_Write_Pres, bleCharacteristicUuid), \n\t\tproperty, permission, ATMO_GetMaxValueSize(3, 64, types));\n\t\n\tATMO_BLE_GATTSRegisterCharacteristicAbilityHandle(\n\t\tATMO_PROPERTY(BLE_Write_Pres, instance),\n\t\tATMO_VARIABLE(BLE_Write_Pres, bleCharacteristicHandle), \n\t\tATMO_BLE_Characteristic_Written, \n\t\tATMO_ABILITY(BLE_Write_Pres, written));\n\t\n\treturn ATMO_Status_Success;\n\t",
              "setValue": "\n\t\n\t// Convert to the desired write data type\n\tATMO_Value_t convertedValue;\n\tATMO_InitValue(&convertedValue);\n\tATMO_CreateValueConverted(&convertedValue, ATMO_PROPERTY(BLE_Write_Pres, readDataType), in);\n\n\tATMO_BLE_GATTSSetCharacteristic(\n\t\tATMO_PROPERTY(BLE_Write_Pres, instance),\n\t\tATMO_VARIABLE(BLE_Write_Pres, bleCharacteristicHandle),\n\t\tconvertedValue.size, \n\t\t(uint8_t *)convertedValue.data,\n\t\tNULL);\n\t\n\tATMO_FreeValue(&convertedValue);\n\t\t\n\treturn ATMO_Status_Success;\n\t",
              "written": "\n\tATMO_CreateValueConverted(out, ATMO_PROPERTY(BLE_Write_Pres, writeDataType), in);\n\treturn ATMO_Status_Success;\n\t",
              "subscibed": "\treturn ATMO_Status_Success;",
              "unsubscribed": "\treturn ATMO_Status_Success;"
            },
            "variables": {
              "bleServiceHandle": {
                "type": "ATMO_BLE_Handle_t"
              },
              "bleCharacteristicHandle": {
                "type": "ATMO_BLE_Handle_t"
              }
            },
            "embeddedPropertyConversions": {
              "bleServiceUuid": "string",
              "bleCharacteristicUuid": "string"
            },
            "codeUserChanged": {
              "setup": false,
              "setValue": false,
              "written": false,
              "subscibed": false,
              "unsubscribed": false
            },
            "instance": "ATMO_DRIVERINSTANCE_BLE_BLE1",
            "bleServiceUuid": "dbc7024c-dede-49a1-8dd8-43238503ba65",
            "bleCharacteristicUuid": "dbc7024c-dede-49a1-8dd8-43238503ba67",
            "read": true,
            "write": true,
            "notify": false,
            "readDataType": "ATMO_DATATYPE_FLOAT",
            "writeDataType": "ATMO_DATATYPE_FLOAT",
            "notifyDataType": "ATMO_DATATYPE_STRING"
          },
          "meta": {
            "editorX": 397,
            "editorY": 386,
            "lastTrigger": "written"
          },
          "triggers": {
            "triggered": [],
            "written": [],
            "subscibed": [],
            "unsubscribed": []
          },
          "interruptAbilities": {
            "trigger": false,
            "setup": false,
            "setValue": "valueSet",
            "written": false,
            "subscibed": false,
            "unsubscribed": false
          },
          "abilities": [
            {
              "name": "trigger",
              "triggers": [
                "triggered"
              ]
            },
            {
              "name": "setup",
              "triggers": []
            },
            {
              "name": "setValue",
              "triggers": []
            },
            {
              "name": "written",
              "triggers": [
                "written"
              ]
            },
            {
              "name": "subscibed",
              "triggers": [
                "subscibed"
              ]
            },
            {
              "name": "unsubscribed",
              "triggers": [
                "unsubscribed"
              ]
            }
          ]
        },
        {
          "name": "BLE_Write_Humi",
          "type": "EmbeddedBLECharacteristicCustom",
          "variants": [
            "embedded",
            "triggers",
            "abilities",
            "properties",
            "variables",
            "ble"
          ],
          "properties": {
            "errorData": {},
            "code": {
              "trigger": "\treturn ATMO_Status_Success;",
              "setup": "\n\tATMO_BLE_GATTSAddService(\n\t\tATMO_PROPERTY(BLE_Write_Humi, instance),\n\t\t&ATMO_VARIABLE(BLE_Write_Humi, bleServiceHandle), \n\t\tATMO_PROPERTY(BLE_Write_Humi, bleServiceUuid));\n\t\n\tuint8_t property = 0;\n\tuint8_t permission = 0;\n\t\n\tproperty |= ATMO_PROPERTY(BLE_Write_Humi, read) ? ATMO_BLE_Property_Read : 0;\n\tproperty |= ATMO_PROPERTY(BLE_Write_Humi, write) ? ATMO_BLE_Property_Write : 0;\n\tproperty |= ATMO_PROPERTY(BLE_Write_Humi, notify) ? ATMO_BLE_Property_Notify : 0;\n\n\tpermission |= ATMO_PROPERTY(BLE_Write_Humi, read) ? ATMO_BLE_Permission_Read : 0;\n\tpermission |= ATMO_PROPERTY(BLE_Write_Humi, write) ? ATMO_BLE_Permission_Write : 0;\n\n\tATMO_DATATYPE types[3] = {ATMO_PROPERTY(BLE_Write_Humi, writeDataType), ATMO_PROPERTY(BLE_Write_Humi, readDataType), ATMO_PROPERTY(BLE_Write_Humi, notifyDataType)};\n\t\n\tATMO_BLE_GATTSAddCharacteristic(\n\t\tATMO_PROPERTY(BLE_Write_Humi, instance),\n\t\t&ATMO_VARIABLE(BLE_Write_Humi, bleCharacteristicHandle), \n\t\tATMO_VARIABLE(BLE_Write_Humi, bleServiceHandle), \n\t\tATMO_PROPERTY(BLE_Write_Humi, bleCharacteristicUuid), \n\t\tproperty, permission, ATMO_GetMaxValueSize(3, 64, types));\n\t\n\tATMO_BLE_GATTSRegisterCharacteristicAbilityHandle(\n\t\tATMO_PROPERTY(BLE_Write_Humi, instance),\n\t\tATMO_VARIABLE(BLE_Write_Humi, bleCharacteristicHandle), \n\t\tATMO_BLE_Characteristic_Written, \n\t\tATMO_ABILITY(BLE_Write_Humi, written));\n\t\n\treturn ATMO_Status_Success;\n\t",
              "setValue": "\n\t\n\t// Convert to the desired write data type\n\tATMO_Value_t convertedValue;\n\tATMO_InitValue(&convertedValue);\n\tATMO_CreateValueConverted(&convertedValue, ATMO_PROPERTY(BLE_Write_Humi, readDataType), in);\n\n\tATMO_BLE_GATTSSetCharacteristic(\n\t\tATMO_PROPERTY(BLE_Write_Humi, instance),\n\t\tATMO_VARIABLE(BLE_Write_Humi, bleCharacteristicHandle),\n\t\tconvertedValue.size, \n\t\t(uint8_t *)convertedValue.data,\n\t\tNULL);\n\t\n\tATMO_FreeValue(&convertedValue);\n\t\t\n\treturn ATMO_Status_Success;\n\t",
              "written": "\n\tATMO_CreateValueConverted(out, ATMO_PROPERTY(BLE_Write_Humi, writeDataType), in);\n\treturn ATMO_Status_Success;\n\t",
              "subscibed": "\treturn ATMO_Status_Success;",
              "unsubscribed": "\treturn ATMO_Status_Success;"
            },
            "variables": {
              "bleServiceHandle": {
                "type": "ATMO_BLE_Handle_t"
              },
              "bleCharacteristicHandle": {
                "type": "ATMO_BLE_Handle_t"
              }
            },
            "embeddedPropertyConversions": {
              "bleServiceUuid": "string",
              "bleCharacteristicUuid": "string"
            },
            "codeUserChanged": {
              "setup": false,
              "setValue": false,
              "written": false,
              "subscibed": false,
              "unsubscribed": false
            },
            "instance": "ATMO_DRIVERINSTANCE_BLE_BLE1",
            "bleServiceUuid": "dbc7024c-dede-49a1-8dd8-43238503ba65",
            "bleCharacteristicUuid": "dbc7024c-dede-49a1-8dd8-43238503ba68",
            "read": true,
            "write": true,
            "notify": false,
            "readDataType": "ATMO_DATATYPE_FLOAT",
            "writeDataType": "ATMO_DATATYPE_FLOAT",
            "notifyDataType": "ATMO_DATATYPE_STRING"
          },
          "meta": {
            "editorX": 398,
            "editorY": 499,
            "lastTrigger": "written"
          },
          "triggers": {
            "triggered": [],
            "written": [],
            "subscibed": [],
            "unsubscribed": []
          },
          "interruptAbilities": {
            "trigger": false,
            "setup": false,
            "setValue": "valueSet",
            "written": false,
            "subscibed": false,
            "unsubscribed": false
          },
          "abilities": [
            {
              "name": "trigger",
              "triggers": [
                "triggered"
              ]
            },
            {
              "name": "setup",
              "triggers": []
            },
            {
              "name": "setValue",
              "triggers": []
            },
            {
              "name": "written",
              "triggers": [
                "written"
              ]
            },
            {
              "name": "subscibed",
              "triggers": [
                "subscibed"
              ]
            },
            {
              "name": "unsubscribed",
              "triggers": [
                "unsubscribed"
              ]
            }
          ]
        }
      ],
      "libraries": {
        "bme680": {
          "libName": "bme680",
          "manufacturer": "Bosch",
          "description": "BME680 is a low power gas, pressure, temperature and humidity sensor",
          "type": "Environmental sensor",
          "icon": "EmbeddedTempHumidity.svg",
          "version": "",
          "eelVersion": "3",
          "shoppingCartLinks": {
            "digikey": {
              "links": {
                "info": "https://www.digikey.com/product-detail/en/bosch-sensortec/SHUTTLE-BOARD-BME680/828-1078-ND/7401318"
              },
              "cartData": {
                "part": "828-1078-ND",
                "source": "dkstudio",
                "qty": "1"
              }
            }
          },
          "requires": [
            "embedded",
            "i2c"
          ],
          "elements": [
            {
              "name": "BME680",
              "type": "EmbeddedBME680",
              "icon": "EmbeddedTempHumidity.svg",
              "defaultAbility": "readTemperature",
              "defaultTrigger": "temperatureRead",
              "hidden": false,
              "abilities": [
                {
                  "name": "setup",
                  "hidden": true,
                  "code": "BME680_Config_t config;\nconfig.i2cInstance = ATMO_PROPERTY( undefined, i2cInstance );\nconfig.i2cAddr = ATMO_PROPERTY( undefined, i2cAddress );\n\nif ( !BME680_Init( &config ) )\n{\n\treturn ATMO_Status_Fail;\n}\n\nreturn ATMO_Status_Success;"
                },
                {
                  "name": "readTemperature",
                  "triggers": [
                    "temperatureRead"
                  ],
                  "code": "float temperature = 0.0;\n\nif ( BME680_GetTempData( &temperature ) != BME680_Status_Success )\n{\n\treturn ATMO_Status_Fail;\n}\n\nATMO_CreateValueFloat( out, temperature );\n\nreturn ATMO_Status_Success;"
                },
                {
                  "name": "readHumidity",
                  "triggers": [
                    "humidityRead"
                  ],
                  "code": "float humidity = 0.0;\n\nif ( BME680_GetHumidity( &humidity ) != BME680_Status_Success )\n{\n\treturn ATMO_Status_Fail;\n}\n\nATMO_CreateValueFloat( out, humidity );\n\nreturn ATMO_Status_Success;"
                },
                {
                  "name": "readPressure",
                  "triggers": [
                    "pressureRead"
                  ],
                  "code": "float pressure = 0.0;\n\nif ( BME680_GetPressure( &pressure ) != BME680_Status_Success )\n{\n\treturn ATMO_Status_Fail;\n}\n\nATMO_CreateValueFloat( out, pressure );\n\nreturn ATMO_Status_Success;"
                },
                {
                  "name": "readGasResistance",
                  "triggers": [
                    "gasResistanceRead"
                  ],
                  "code": "float gas_resistance = 0.0;\n\nif ( BME680_GetGasRes( &gas_resistance ) != BME680_Status_Success )\n{\n\treturn ATMO_Status_Fail;\n}\n\nATMO_CreateValueFloat( out, gas_resistance );\n\nreturn ATMO_Status_Success;"
                }
              ],
              "properties": [
                {
                  "name": "i2cInstance",
                  "input": "driverInstance",
                  "driverType": "i2c"
                },
                {
                  "name": "i2cAddress",
                  "input": "select",
                  "inputOptions": [
                    "0x76",
                    "0x77"
                  ],
                  "value": "0x76"
                }
              ],
              "triggers": [],
              "variables": [],
              "language": {
                "en-US": {
                  "EmbeddedBME680": "BME680 Environmental",
                  "i2cInstance": "I2C Driver Instance",
                  "i2cAddress": "I2C Address",
                  "setup": "Setup",
                  "readTemperature": "Read Temperature (C)",
                  "temperatureRead": "Temperature Read",
                  "readHumidity": "Read Humidity (%rh)",
                  "humidityRead": "Humidity Read",
                  "readPressure": "Read Pressure (Pa)",
                  "pressureRead": "Pressure Read",
                  "readGasResistance": "Read Gas Resistance (ohm)",
                  "gasResistanceRead": "Gas Resistance Read"
                }
              }
            }
          ],
          "files": {
            "common": {
              "headers": {
                "bme680.h": "#ifndef ATMO_BME680_H_\n#define ATMO_BME680_H_\n\n#include \"../app_src/atmosphere_platform.h\"\n\ntypedef struct\n{\n\tATMO_DriverInstanceHandle_t i2cInstance;\n\tuint8_t i2cAddr;\n} BME680_Config_t;\n\ntypedef enum\n{\n\tBME680_Status_Success = 0,\n\tBME680_Status_Fail\n} BME680_Status_t;\n\nBME680_Status_t BME680_Init( BME680_Config_t *config );\n\nBME680_Status_t BME680_GetPressure( float *pressureHpa );\n\nBME680_Status_t BME680_GetTempData( float *tempC );\n\nBME680_Status_t BME680_GetHumidity( float *humidity );\n\nBME680_Status_t BME680_GetGasRes( float *gas_resistance );\n\n#endif\n",
                "bme680_defs.h": "/**\n * Copyright (C) 2017 - 2018 Bosch Sensortec GmbH\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *\n * Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n *\n * Neither the name of the copyright holder nor the names of the\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n * CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER\n * OR CONTRIBUTORS BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,\n * OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO,\n * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS\n * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\n *\n * The information provided is believed to be accurate and reliable.\n * The copyright holder assumes no responsibility\n * for the consequences of use\n * of such information nor for any infringement of patents or\n * other rights of third parties which may result from its use.\n * No license is granted by implication or otherwise under any patent or\n * patent rights of the copyright holder.\n *\n * @file\tbme680_defs.h\n * @date\t22 Feb 2018\n * @version\t3.5.8\n * @brief\n *\n */\n\n/*! @file bme680_defs.h\n @brief Sensor driver for BME680 sensor */\n/*!\n * @defgroup BME680_DRIVER_GRP BME680 SENSOR API\n * @brief\n * @{*/\n#ifndef BME680_DEFS_H_\n#define BME680_DEFS_H_\n\n/********************************************************/\n/* header includes */\n#ifdef __KERNEL__\n#include <linux/types.h>\n#include <linux/kernel.h>\n#else\n#include \"../app_src/atmosphere_platform.h\"\n#endif\n\n/******************************************************************************/\n/*! @name\t\tCommon macros\t\t\t\t\t      */\n/******************************************************************************/\n\n#if !defined(UINT8_C) && !defined(INT8_C)\n#define INT8_C(x)       S8_C(x)\n#define UINT8_C(x)      U8_C(x)\n#endif\n\n#if !defined(UINT16_C) && !defined(INT16_C)\n#define INT16_C(x)      S16_C(x)\n#define UINT16_C(x)     U16_C(x)\n#endif\n\n#if !defined(INT32_C) && !defined(UINT32_C)\n#define INT32_C(x)      S32_C(x)\n#define UINT32_C(x)     U32_C(x)\n#endif\n\n#if !defined(INT64_C) && !defined(UINT64_C)\n#define INT64_C(x)      S64_C(x)\n#define UINT64_C(x)     U64_C(x)\n#endif\n\n/**@}*/\n\n/**\\name C standard macros */\n#ifndef NULL\n#ifdef __cplusplus\n#define NULL   0\n#else\n#define NULL   ((void *) 0)\n#endif\n#endif\n\n/** BME680 configuration macros */\n/** Enable or un-comment the macro to provide floating point data output */\n#ifndef BME680_FLOAT_POINT_COMPENSATION\n#define BME680_FLOAT_POINT_COMPENSATION\n#endif\n\n/** BME680 General config */\n#define BME680_POLL_PERIOD_MS\t\tUINT8_C(10)\n\n/** BME680 I2C addresses */\n#define BME680_I2C_ADDR_PRIMARY\t\tUINT8_C(0x76)\n#define BME680_I2C_ADDR_SECONDARY\tUINT8_C(0x77)\n\n/** BME680 unique chip identifier */\n#define BME680_CHIP_ID  UINT8_C(0x61)\n\n/** BME680 coefficients related defines */\n#define BME680_COEFF_SIZE\t\tUINT8_C(41)\n#define BME680_COEFF_ADDR1_LEN\t\tUINT8_C(25)\n#define BME680_COEFF_ADDR2_LEN\t\tUINT8_C(16)\n\n/** BME680 field_x related defines */\n#define BME680_FIELD_LENGTH\t\tUINT8_C(15)\n#define BME680_FIELD_ADDR_OFFSET\tUINT8_C(17)\n\n/** Soft reset command */\n#define BME680_SOFT_RESET_CMD   UINT8_C(0xb6)\n\n/** Error code definitions */\n#define BME680_OK\t\tINT8_C(0)\n/* Errors */\n#define BME680_E_NULL_PTR\t\t    INT8_C(-1)\n#define BME680_E_COM_FAIL\t\t    INT8_C(-2)\n#define BME680_E_DEV_NOT_FOUND\t\tINT8_C(-3)\n#define BME680_E_INVALID_LENGTH\t\tINT8_C(-4)\n\n/* Warnings */\n#define BME680_W_DEFINE_PWR_MODE\tINT8_C(1)\n#define BME680_W_NO_NEW_DATA        INT8_C(2)\n\n/* Info's */\n#define BME680_I_MIN_CORRECTION\t\tUINT8_C(1)\n#define BME680_I_MAX_CORRECTION\t\tUINT8_C(2)\n\n/** Register map */\n/** Other coefficient's address */\n#define BME680_ADDR_RES_HEAT_VAL_ADDR\tUINT8_C(0x00)\n#define BME680_ADDR_RES_HEAT_RANGE_ADDR\tUINT8_C(0x02)\n#define BME680_ADDR_RANGE_SW_ERR_ADDR\tUINT8_C(0x04)\n#define BME680_ADDR_SENS_CONF_START\tUINT8_C(0x5A)\n#define BME680_ADDR_GAS_CONF_START\tUINT8_C(0x64)\n\n/** Field settings */\n#define BME680_FIELD0_ADDR\t\tUINT8_C(0x1d)\n\n/** Heater settings */\n#define BME680_RES_HEAT0_ADDR\t\tUINT8_C(0x5a)\n#define BME680_GAS_WAIT0_ADDR\t\tUINT8_C(0x64)\n\n/** Sensor configuration registers */\n#define BME680_CONF_HEAT_CTRL_ADDR\t\tUINT8_C(0x70)\n#define BME680_CONF_ODR_RUN_GAS_NBC_ADDR\tUINT8_C(0x71)\n#define BME680_CONF_OS_H_ADDR\t\t\tUINT8_C(0x72)\n#define BME680_MEM_PAGE_ADDR\t\t\tUINT8_C(0xf3)\n#define BME680_CONF_T_P_MODE_ADDR\t\tUINT8_C(0x74)\n#define BME680_CONF_ODR_FILT_ADDR\t\tUINT8_C(0x75)\n\n/** Coefficient's address */\n#define BME680_COEFF_ADDR1\tUINT8_C(0x89)\n#define BME680_COEFF_ADDR2\tUINT8_C(0xe1)\n\n/** Chip identifier */\n#define BME680_CHIP_ID_ADDR\tUINT8_C(0xd0)\n\n/** Soft reset register */\n#define BME680_SOFT_RESET_ADDR\t\tUINT8_C(0xe0)\n\n/** Heater control settings */\n#define BME680_ENABLE_HEATER\t\tUINT8_C(0x00)\n#define BME680_DISABLE_HEATER\t\tUINT8_C(0x08)\n\n/** Gas measurement settings */\n#define BME680_DISABLE_GAS_MEAS\t\tUINT8_C(0x00)\n#define BME680_ENABLE_GAS_MEAS\t\tUINT8_C(0x01)\n\n/** Over-sampling settings */\n#define BME680_OS_NONE\t\tUINT8_C(0)\n#define BME680_OS_1X\t\tUINT8_C(1)\n#define BME680_OS_2X\t\tUINT8_C(2)\n#define BME680_OS_4X\t\tUINT8_C(3)\n#define BME680_OS_8X\t\tUINT8_C(4)\n#define BME680_OS_16X\t\tUINT8_C(5)\n\n/** IIR filter settings */\n#define BME680_FILTER_SIZE_0\tUINT8_C(0)\n#define BME680_FILTER_SIZE_1\tUINT8_C(1)\n#define BME680_FILTER_SIZE_3\tUINT8_C(2)\n#define BME680_FILTER_SIZE_7\tUINT8_C(3)\n#define BME680_FILTER_SIZE_15\tUINT8_C(4)\n#define BME680_FILTER_SIZE_31\tUINT8_C(5)\n#define BME680_FILTER_SIZE_63\tUINT8_C(6)\n#define BME680_FILTER_SIZE_127\tUINT8_C(7)\n\n/** Power mode settings */\n#define BME680_SLEEP_MODE\tUINT8_C(0)\n#define BME680_FORCED_MODE\tUINT8_C(1)\n\n/** Delay related macro declaration */\n#define BME680_RESET_PERIOD\tUINT32_C(10)\n\n/** SPI memory page settings */\n#define BME680_MEM_PAGE0\tUINT8_C(0x10)\n#define BME680_MEM_PAGE1\tUINT8_C(0x00)\n\n/** Ambient humidity shift value for compensation */\n#define BME680_HUM_REG_SHIFT_VAL\tUINT8_C(4)\n\n/** Run gas enable and disable settings */\n#define BME680_RUN_GAS_DISABLE\tUINT8_C(0)\n#define BME680_RUN_GAS_ENABLE\tUINT8_C(1)\n\n/** Buffer length macro declaration */\n#define BME680_TMP_BUFFER_LENGTH\tUINT8_C(40)\n#define BME680_REG_BUFFER_LENGTH\tUINT8_C(6)\n#define BME680_FIELD_DATA_LENGTH\tUINT8_C(3)\n#define BME680_GAS_REG_BUF_LENGTH\tUINT8_C(20)\n\n/** Settings selector */\n#define BME680_OST_SEL\t\t\tUINT16_C(1)\n#define BME680_OSP_SEL\t\t\tUINT16_C(2)\n#define BME680_OSH_SEL\t\t\tUINT16_C(4)\n#define BME680_GAS_MEAS_SEL\t\tUINT16_C(8)\n#define BME680_FILTER_SEL\t\tUINT16_C(16)\n#define BME680_HCNTRL_SEL\t\tUINT16_C(32)\n#define BME680_RUN_GAS_SEL\t\tUINT16_C(64)\n#define BME680_NBCONV_SEL\t\tUINT16_C(128)\n#define BME680_GAS_SENSOR_SEL\t\t(BME680_GAS_MEAS_SEL | BME680_RUN_GAS_SEL | BME680_NBCONV_SEL)\n\n/** Number of conversion settings*/\n#define BME680_NBCONV_MIN\t\tUINT8_C(0)\n#define BME680_NBCONV_MAX\t\tUINT8_C(10)\n\n/** Mask definitions */\n#define BME680_GAS_MEAS_MSK\tUINT8_C(0x30)\n#define BME680_NBCONV_MSK\tUINT8_C(0X0F)\n#define BME680_FILTER_MSK\tUINT8_C(0X1C)\n#define BME680_OST_MSK\t\tUINT8_C(0XE0)\n#define BME680_OSP_MSK\t\tUINT8_C(0X1C)\n#define BME680_OSH_MSK\t\tUINT8_C(0X07)\n#define BME680_HCTRL_MSK\tUINT8_C(0x08)\n#define BME680_RUN_GAS_MSK\tUINT8_C(0x10)\n#define BME680_MODE_MSK\t\tUINT8_C(0x03)\n#define BME680_RHRANGE_MSK\tUINT8_C(0x30)\n#define BME680_RSERROR_MSK\tUINT8_C(0xf0)\n#define BME680_NEW_DATA_MSK\tUINT8_C(0x80)\n#define BME680_GAS_INDEX_MSK\tUINT8_C(0x0f)\n#define BME680_GAS_RANGE_MSK\tUINT8_C(0x0f)\n#define BME680_GASM_VALID_MSK\tUINT8_C(0x20)\n#define BME680_HEAT_STAB_MSK\tUINT8_C(0x10)\n#define BME680_MEM_PAGE_MSK\tUINT8_C(0x10)\n#define BME680_SPI_RD_MSK\tUINT8_C(0x80)\n#define BME680_SPI_WR_MSK\tUINT8_C(0x7f)\n#define\tBME680_BIT_H1_DATA_MSK\tUINT8_C(0x0F)\n\n/** Bit position definitions for sensor settings */\n#define BME680_GAS_MEAS_POS\tUINT8_C(4)\n#define BME680_FILTER_POS\tUINT8_C(2)\n#define BME680_OST_POS\t\tUINT8_C(5)\n#define BME680_OSP_POS\t\tUINT8_C(2)\n#define BME680_RUN_GAS_POS\tUINT8_C(4)\n\n/** Array Index to Field data mapping for Calibration Data*/\n#define BME680_T2_LSB_REG\t(1)\n#define BME680_T2_MSB_REG\t(2)\n#define BME680_T3_REG\t\t(3)\n#define BME680_P1_LSB_REG\t(5)\n#define BME680_P1_MSB_REG\t(6)\n#define BME680_P2_LSB_REG\t(7)\n#define BME680_P2_MSB_REG\t(8)\n#define BME680_P3_REG\t\t(9)\n#define BME680_P4_LSB_REG\t(11)\n#define BME680_P4_MSB_REG\t(12)\n#define BME680_P5_LSB_REG\t(13)\n#define BME680_P5_MSB_REG\t(14)\n#define BME680_P7_REG\t\t(15)\n#define BME680_P6_REG\t\t(16)\n#define BME680_P8_LSB_REG\t(19)\n#define BME680_P8_MSB_REG\t(20)\n#define BME680_P9_LSB_REG\t(21)\n#define BME680_P9_MSB_REG\t(22)\n#define BME680_P10_REG\t\t(23)\n#define BME680_H2_MSB_REG\t(25)\n#define BME680_H2_LSB_REG\t(26)\n#define BME680_H1_LSB_REG\t(26)\n#define BME680_H1_MSB_REG\t(27)\n#define BME680_H3_REG\t\t(28)\n#define BME680_H4_REG\t\t(29)\n#define BME680_H5_REG\t\t(30)\n#define BME680_H6_REG\t\t(31)\n#define BME680_H7_REG\t\t(32)\n#define BME680_T1_LSB_REG\t(33)\n#define BME680_T1_MSB_REG\t(34)\n#define BME680_GH2_LSB_REG\t(35)\n#define BME680_GH2_MSB_REG\t(36)\n#define BME680_GH1_REG\t\t(37)\n#define BME680_GH3_REG\t\t(38)\n\n/** BME680 register buffer index settings*/\n#define BME680_REG_FILTER_INDEX\t\tUINT8_C(5)\n#define BME680_REG_TEMP_INDEX\t\tUINT8_C(4)\n#define BME680_REG_PRES_INDEX\t\tUINT8_C(4)\n#define BME680_REG_HUM_INDEX\t\tUINT8_C(2)\n#define BME680_REG_NBCONV_INDEX\t\tUINT8_C(1)\n#define BME680_REG_RUN_GAS_INDEX\tUINT8_C(1)\n#define BME680_REG_HCTRL_INDEX\t\tUINT8_C(0)\n\n/** BME680 pressure calculation macros */\n/*! This max value is used to provide precedence to multiplication or division\n * in pressure compensation equation to achieve least loss of precision and\n * avoiding overflows.\n * i.e Comparing value, BME680_MAX_OVERFLOW_VAL = INT32_C(1 << 30)\n */\n#define BME680_MAX_OVERFLOW_VAL      INT32_C(0x40000000)\n\n/** Macro to combine two 8 bit data's to form a 16 bit data */\n#define BME680_CONCAT_BYTES(msb, lsb)\t(((uint16_t)msb << 8) | (uint16_t)lsb)\n\n/** Macro to SET and GET BITS of a register */\n#define BME680_SET_BITS(reg_data, bitname, data) \\\n\t\t((reg_data & ~(bitname##_MSK)) | \\\n\t\t((data << bitname##_POS) & bitname##_MSK))\n#define BME680_GET_BITS(reg_data, bitname)\t((reg_data & (bitname##_MSK)) >> \\\n\t(bitname##_POS))\n\n/** Macro variant to handle the bitname position if it is zero */\n#define BME680_SET_BITS_POS_0(reg_data, bitname, data) \\\n\t\t\t\t((reg_data & ~(bitname##_MSK)) | \\\n\t\t\t\t(data & bitname##_MSK))\n#define BME680_GET_BITS_POS_0(reg_data, bitname)  (reg_data & (bitname##_MSK))\n\n/** Type definitions */\n/*!\n * Generic communication function pointer\n * @param[in] dev_id: Place holder to store the id of the device structure\n *                    Can be used to store the index of the Chip select or\n *                    I2C address of the device.\n * @param[in] reg_addr:\tUsed to select the register the where data needs to\n *                      be read from or written to.\n * @param[in/out] reg_data: Data array to read/write\n * @param[in] len: Length of the data array\n */\ntypedef int8_t ( *bme680_com_fptr_t )( uint8_t dev_id, uint8_t reg_addr, uint8_t *data, uint16_t len );\n\n/*!\n * Delay function pointer\n * @param[in] period: Time period in milliseconds\n */\ntypedef void ( *bme680_delay_fptr_t )( uint32_t period );\n\n/*!\n * @brief Interface selection Enumerations\n */\nenum bme680_intf\n{\n\t/*! SPI interface */\n\tBME680_SPI_INTF,\n\t/*! I2C interface */\n\tBME680_I2C_INTF\n};\n\n/* structure definitions */\n/*!\n * @brief Sensor field data structure\n */\nstruct\tbme680_field_data\n{\n\t/*! Contains new_data, gasm_valid & heat_stab */\n\tuint8_t status;\n\t/*! The index of the heater profile used */\n\tuint8_t gas_index;\n\t/*! Measurement index to track order */\n\tuint8_t meas_index;\n\n#ifndef BME680_FLOAT_POINT_COMPENSATION\n\t/*! Temperature in degree celsius x100 */\n\tint16_t temperature;\n\t/*! Pressure in Pascal */\n\tuint32_t pressure;\n\t/*! Humidity in % relative humidity x1000 */\n\tuint32_t humidity;\n\t/*! Gas resistance in Ohms */\n\tuint32_t gas_resistance;\n#else\n\t/*! Temperature in degree celsius */\n\tfloat temperature;\n\t/*! Pressure in Pascal */\n\tfloat pressure;\n\t/*! Humidity in % relative humidity x1000 */\n\tfloat humidity;\n\t/*! Gas resistance in Ohms */\n\tfloat gas_resistance;\n\n#endif\n\n};\n\n/*!\n * @brief Structure to hold the Calibration data\n */\nstruct\tbme680_calib_data\n{\n\t/*! Variable to store calibrated humidity data */\n\tuint16_t par_h1;\n\t/*! Variable to store calibrated humidity data */\n\tuint16_t par_h2;\n\t/*! Variable to store calibrated humidity data */\n\tint8_t par_h3;\n\t/*! Variable to store calibrated humidity data */\n\tint8_t par_h4;\n\t/*! Variable to store calibrated humidity data */\n\tint8_t par_h5;\n\t/*! Variable to store calibrated humidity data */\n\tuint8_t par_h6;\n\t/*! Variable to store calibrated humidity data */\n\tint8_t par_h7;\n\t/*! Variable to store calibrated gas data */\n\tint8_t par_gh1;\n\t/*! Variable to store calibrated gas data */\n\tint16_t par_gh2;\n\t/*! Variable to store calibrated gas data */\n\tint8_t par_gh3;\n\t/*! Variable to store calibrated temperature data */\n\tuint16_t par_t1;\n\t/*! Variable to store calibrated temperature data */\n\tint16_t par_t2;\n\t/*! Variable to store calibrated temperature data */\n\tint8_t par_t3;\n\t/*! Variable to store calibrated pressure data */\n\tuint16_t par_p1;\n\t/*! Variable to store calibrated pressure data */\n\tint16_t par_p2;\n\t/*! Variable to store calibrated pressure data */\n\tint8_t par_p3;\n\t/*! Variable to store calibrated pressure data */\n\tint16_t par_p4;\n\t/*! Variable to store calibrated pressure data */\n\tint16_t par_p5;\n\t/*! Variable to store calibrated pressure data */\n\tint8_t par_p6;\n\t/*! Variable to store calibrated pressure data */\n\tint8_t par_p7;\n\t/*! Variable to store calibrated pressure data */\n\tint16_t par_p8;\n\t/*! Variable to store calibrated pressure data */\n\tint16_t par_p9;\n\t/*! Variable to store calibrated pressure data */\n\tuint8_t par_p10;\n\n#ifndef BME680_FLOAT_POINT_COMPENSATION\n\t/*! Variable to store t_fine size */\n\tint32_t t_fine;\n#else\n\t/*! Variable to store t_fine size */\n\tfloat t_fine;\n#endif\n\t/*! Variable to store heater resistance range */\n\tuint8_t res_heat_range;\n\t/*! Variable to store heater resistance value */\n\tint8_t res_heat_val;\n\t/*! Variable to store error range */\n\tint8_t range_sw_err;\n};\n\n/*!\n * @brief BME680 sensor settings structure which comprises of ODR,\n * over-sampling and filter settings.\n */\nstruct\tbme680_tph_sett\n{\n\t/*! Humidity oversampling */\n\tuint8_t os_hum;\n\t/*! Temperature oversampling */\n\tuint8_t os_temp;\n\t/*! Pressure oversampling */\n\tuint8_t os_pres;\n\t/*! Filter coefficient */\n\tuint8_t filter;\n};\n\n/*!\n * @brief BME680 gas sensor which comprises of gas settings\n *  and status parameters\n */\nstruct\tbme680_gas_sett\n{\n\t/*! Variable to store nb conversion */\n\tuint8_t nb_conv;\n\t/*! Variable to store heater control */\n\tuint8_t heatr_ctrl;\n\t/*! Run gas enable value */\n\tuint8_t run_gas;\n\t/*! Heater temperature value */\n\tuint16_t heatr_temp;\n\t/*! Duration profile value */\n\tuint16_t heatr_dur;\n};\n\n/*!\n * @brief BME680 device structure\n */\nstruct\tbme680_dev\n{\n\t/*! Chip Id */\n\tuint8_t chip_id;\n\t/*! Device Id */\n\tuint8_t dev_id;\n\t/*! SPI/I2C interface */\n\tenum bme680_intf intf;\n\t/*! Memory page used */\n\tuint8_t mem_page;\n\t/*! Ambient temperature in Degree C */\n\tint8_t amb_temp;\n\t/*! Sensor calibration data */\n\tstruct bme680_calib_data calib;\n\t/*! Sensor settings */\n\tstruct bme680_tph_sett tph_sett;\n\t/*! Gas Sensor settings */\n\tstruct bme680_gas_sett gas_sett;\n\t/*! Sensor power modes */\n\tuint8_t power_mode;\n\t/*! New sensor fields */\n\tuint8_t new_fields;\n\t/*! Store the info messages */\n\tuint8_t info_msg;\n\t/*! Bus read function pointer */\n\tbme680_com_fptr_t read;\n\t/*! Bus write function pointer */\n\tbme680_com_fptr_t write;\n\t/*! delay function pointer */\n\tbme680_delay_fptr_t delay_ms;\n\t/*! Communication function result */\n\tint8_t com_rslt;\n};\n\n\n\n#endif /* BME680_DEFS_H_ */\n/** @}*/\n/** @}*/\n",
                "bme680_env.h": "//-----------------------------------------------------------------------------\n// Copyright (c) 2018 Semiconductor Components Industries LLC\n// (d/b/a \"ON Semiconductor\").  All rights reserved.\n// This software and/or documentation is licensed by ON Semiconductor under\n// limited terms and conditions.  The terms and conditions pertaining to the\n// software and/or documentation are available at\n// http://www.onsemi.com/site/pdf/ONSEMI_T&C.pdf (\"ON Semiconductor Standard\n// Terms and Conditions of Sale, Section 8 Software\") and if applicable the\n// software license agreement.  Do not use this software and/or documentation\n// unless you have carefully read and you agree to the limited terms and\n// conditions.  By using this software and/or documentation, you agree to the\n// limited terms and conditions.\n//-----------------------------------------------------------------------------\n//! \\file RTE_BDK_BME680_ENV.h\n//!\n//! This file contains the Run Time Configuration (RTE) options for BME680_ENV\n//! CMSIS Component.\n//!\n//! These options can be edited by opening this file in CMSIS Configuration\n//! Wizard Editor that is part of Eclipse installation.\n//!\n//! \\addtogroup BDK_GRP\n//! \\{\n//! \\addtogroup COMPONENTS\n//! \\{\n//! \\addtogroup BME680_ENV_GRP\n//! \\{\n//! \\name Run Time Environment Configuration\n//!\n//! These parameters are part of the \\ref RTE_BME680_ENV.h RTE configuration\n//! file and can be used to adjust library behavior.\n//! This file is copied into the Eclipse project when the BME680_ENV component\n//! is selected and can be edited by using the <i>CMIS Configuration Wizard</i>\n//! editor.\n//!\n//! \\image html rte_bme680_env.jpg\n//!\n//-----------------------------------------------------------------------------\n\n#ifndef RTE_BME680_ENV_H_\n#define RTE_BME680_ENV_H_\n\n// <<< Use Configuration Wizard in Context Menu >>>\n\n/** \\def RTE_BME680_ENV_TEMP_ENABLE\n * \\brief Enables or disables temperature measurement.\n *\n * Disabling is discouraged as other measurements depend on temperature\n * measurement for calibration.\n *\n * If disabled a constant value of INT16_MAX will be reported in\n * \\ref BME680_ENV_Data::temperature.\n */\n// <e> Temperature measurement\n// <i> Enables temperature measurement.\n// <i> Disabling is discouraged as other measurements depend on temperature measurement for calibration.\n// <i> If disabled a constant value of INT16_MAX will be reported.\n#ifndef RTE_BME680_ENV_TEMP_ENABLE\n#define RTE_BME680_ENV_TEMP_ENABLE 1\n#endif\n\n#if defined RTE_BME680_ENV_TEMP_ENABLE == 1\n\n/** \\def RTE_BME680_ENV_OS_TEMP\n * \\brief Temperature measurement oversampling setting.\n *\n * Oversampling improves temperature measurement resolution by reducing noise.\n * Higher oversampling values will result in longer measurement duration.\n *\n * \\see\n * Section <b>3.3.1 Temperature Measurement</b> of BME680 datasheet for more\n * details.\n */\n// <o> Oversampling\n// <i> Oversampling improves temperature measurement resolution by reducing noise.\n// <i> Higher oversampling values will result in longer measurement duration.\n// <i> See section '3.3.1 Temperature Measurement' of BME680 datasheet for more details.\n//    <1=> 1x\n//    <2=> 2x\n//    <3=> 4x\n//    <4=> 8x\n//    <5=> 16x\n#define RTE_BME680_ENV_OS_TEMP         2\n\n#else\n#define RTE_BME680_ENV_OS_TEMP         0\n#endif /* defined RTE_BME680_ENV_TEMP_ENABLE == 1 */\n\n// </e>\n\n/** \\def RTE_BME680_ENV_PRES_ENABLE\n * \\brief Enables or disables pressure measurement.\n *\n * If disabled a constant value of UINT32_MAX will be reported in\n * \\ref BME680_ENV_Data::pressure.\n */\n// <e> Pressure measurement\n// <i> Enables pressure measurement.\n// <i> If disabled a constant value of UINT32_MAX will be reported.\n#ifndef RTE_BME680_ENV_PRES_ENABLE\n#define RTE_BME680_ENV_PRES_ENABLE 1\n#endif\n\n#if defined RTE_BME680_ENV_PRES_ENABLE == 1\n\n/** \\def RTE_BME680_ENV_OS_PRES\n * \\brief Pressure measurement oversampling setting.\n *\n * Oversampling improves pressure measurement resolution by reducing noise.\n * Higher oversampling values will result in longer measurement duration.\n *\n * \\see\n * Section <b>3.3.2 Pressure Measurement</b> of BME680 datasheet for more\n * details.\n */\n// <o> Oversampling\n// <i> Oversampling improves pressure measurement resolution by reducing noise.\n// <i> Higher oversampling values will result in longer measurement duration.\n// <i> See section '3.3.2 Pressure Measurement' of BME680 datasheet for more details.\n//    <1=> 1x\n//    <2=> 2x\n//    <3=> 4x\n//    <4=> 8x\n//    <5=> 16x\n#define RTE_BME680_ENV_OS_PRES         2\n\n#else\n#define RTE_BME680_ENV_OS_PRES         0\n#endif /* defined RTE_BME680_ENV_PRES_ENABLE == 1 */\n\n// </e>\n\n/** \\def RTE_BME680_ENV_HUM_ENABLE\n * \\brief Enables or disables humidity measurement.\n *\n * If disabled a constant value of UINT32_MAX will be reported in\n * \\ref BME680_ENV_Data::humidity.\n */\n// <e> Humidity measurement\n// <i> Enables humidity measurement\n// <i> If disabled a constant value of UINT32_MAX will be reported.\n#ifndef RTE_BME680_ENV_HUM_ENABLE\n#define RTE_BME680_ENV_HUM_ENABLE 1\n#endif\n\n#if defined RTE_BME680_ENV_HUM_ENABLE == 1\n\n/** \\def RTE_BME680_ENV_OS_HUM\n * \\brief Humidity measurement oversampling setting.\n *\n * Oversampling improves humidity measurement by reducing noise.\n * Higher oversampling values will result in longer measurement duration.\n *\n * \\see\n * Section <b>3.3.3 Humidity Measurement</b> of BME680 datasheet for more\n * details.\n */\n// <o> Oversampling\n// <i> Higher oversampling setting reduces noise.\n// <i> Higher oversampling values will result in longer measurement duration.\n// <i> See section '3.3.3 Humidity Measurement' of BME680 datasheet for more details.\n//    <1=> 1x\n//    <2=> 2x\n//    <3=> 4x\n//    <4=> 8x\n//    <5=> 16x\n#ifndef RTE_BME680_ENV_OS_HUM\n#define RTE_BME680_ENV_OS_HUM          2\n#endif\n\n#else\n#define RTE_BME680_ENV_OS_HUM          0\n#endif /* defined RTE_BME680_ENV_HUM_ENABLE == 1 */\n\n// </e>\n\n/** \\def RTE_BME680_ENV_FILTER_SIZE\n * \\brief IIR filter coefficient value.\n *\n * Reduces the bandwidth of temperature and pressure output signals and\n * increases the resolution of output data to 20 bit.\n *\n * \\see\n * Section <b>3.3.4 IIR filter</b> of BME680 datasheet for more details.\n */\n// <o> IIR Filter Size\n// <i> Reduces the bandwidth of temperature and pressure output signals and increases the resolution of output data to 20 bit.\n// <i> See section '3.3.4 IIR filter' of BME680 datasheet for more details.\n//    <0=> 0\n//    <1=> 1\n//    <2=> 3\n//    <3=> 7\n//    <4=> 15\n//    <5=> 31\n//    <6=> 63\n//    <7=> 127\n#ifndef RTE_BME680_ENV_FILTER_SIZE\n#define RTE_BME680_ENV_FILTER_SIZE     1\n#endif\n\n// <<< end of configuration section >>>\n\n#endif /* RTE_BME680_ENV_H_ */\n\n//! \\}\n//! \\}\n//! \\}\n//! \\}\n",
                "bme680_reg.h": "/**\n * Copyright (C) 2017 - 2018 Bosch Sensortec GmbH\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *\n * Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n *\n * Neither the name of the copyright holder nor the names of the\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n * CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER\n * OR CONTRIBUTORS BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,\n * OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO,\n * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS\n * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\n *\n * The information provided is believed to be accurate and reliable.\n * The copyright holder assumes no responsibility\n * for the consequences of use\n * of such information nor for any infringement of patents or\n * other rights of third parties which may result from its use.\n * No license is granted by implication or otherwise under any patent or\n * patent rights of the copyright holder.\n *\n * @file\tbme680.h\n * @date\t22 Feb 2018\n * @version\t3.5.8\n * @brief\n *\n */\n/*! @file bme680.h\n @brief Sensor driver for BME680 sensor */\n/*!\n * @defgroup BME680_DRIVER_GRP BME680 SENSOR API\n * @{*/\n#ifndef BME680_H_\n#define BME680_H_\n\n/*! CPP guard */\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n/* Header includes */\n#include \"bme680_defs.h\"\n\n/* function prototype declarations */\n/*!\n *  @brief This API is the entry point.\n *  It reads the chip-id and calibration data from the sensor.\n *\n *  @param[in,out] dev : Structure instance of bme680_dev\n *\n *  @return Result of API execution status\n *  @retval zero -> Success / +ve value -> Warning / -ve value -> Error\n */\nint8_t bme680_init( struct bme680_dev *dev );\n\n/*!\n * @brief This API writes the given data to the register address\n * of the sensor.\n *\n * @param[in] reg_addr : Register address from where the data to be written.\n * @param[in] reg_data : Pointer to data buffer which is to be written\n * in the sensor.\n * @param[in] len : No of bytes of data to write..\n * @param[in] dev : Structure instance of bme680_dev.\n *\n * @return Result of API execution status\n * @retval zero -> Success / +ve value -> Warning / -ve value -> Error\n */\nint8_t bme680_set_regs( const uint8_t *reg_addr, const uint8_t *reg_data, uint8_t len, struct bme680_dev *dev );\n\n/*!\n * @brief This API reads the data from the given register address of the sensor.\n *\n * @param[in] reg_addr : Register address from where the data to be read\n * @param[out] reg_data : Pointer to data buffer to store the read data.\n * @param[in] len : No of bytes of data to be read.\n * @param[in] dev : Structure instance of bme680_dev.\n *\n * @return Result of API execution status\n * @retval zero -> Success / +ve value -> Warning / -ve value -> Error\n */\nint8_t bme680_get_regs( uint8_t reg_addr, uint8_t *reg_data, uint16_t len, struct bme680_dev *dev );\n\n/*!\n * @brief This API performs the soft reset of the sensor.\n *\n * @param[in] dev : Structure instance of bme680_dev.\n *\n * @return Result of API execution status\n * @retval zero -> Success / +ve value -> Warning / -ve value -> Error.\n */\nint8_t bme680_soft_reset( struct bme680_dev *dev );\n\n/*!\n * @brief This API is used to set the power mode of the sensor.\n *\n * @param[in] dev : Structure instance of bme680_dev\n * @note : Pass the value to bme680_dev.power_mode structure variable.\n *\n *  value\t|\tmode\n * -------------|------------------\n *\t0x00\t|\tBME680_SLEEP_MODE\n *\t0x01\t|\tBME680_FORCED_MODE\n *\n * * @return Result of API execution status\n * @retval zero -> Success / +ve value -> Warning / -ve value -> Error\n */\nint8_t bme680_set_sensor_mode( struct bme680_dev *dev );\n\n/*!\n * @brief This API is used to get the power mode of the sensor.\n *\n * @param[in] dev : Structure instance of bme680_dev\n * @note : bme680_dev.power_mode structure variable hold the power mode.\n *\n *  value\t|\tmode\n * ---------|------------------\n *\t0x00\t|\tBME680_SLEEP_MODE\n *\t0x01\t|\tBME680_FORCED_MODE\n *\n * @return Result of API execution status\n * @retval zero -> Success / +ve value -> Warning / -ve value -> Error\n */\nint8_t bme680_get_sensor_mode( struct bme680_dev *dev );\n\n/*!\n * @brief This API is used to set the profile duration of the sensor.\n *\n * @param[in] dev\t   : Structure instance of bme680_dev.\n * @param[in] duration : Duration of the measurement in ms.\n *\n * @return Nothing\n */\nvoid bme680_set_profile_dur( uint16_t duration, struct bme680_dev *dev );\n\n/*!\n * @brief This API is used to get the profile duration of the sensor.\n *\n * @param[in] dev\t   : Structure instance of bme680_dev.\n * @param[in] duration : Duration of the measurement in ms.\n *\n * @return Nothing\n */\nvoid bme680_get_profile_dur( uint16_t *duration, const struct bme680_dev *dev );\n\n/*!\n * @brief This API reads the pressure, temperature and humidity and gas data\n * from the sensor, compensates the data and store it in the bme680_data\n * structure instance passed by the user.\n *\n * @param[out] data: Structure instance to hold the data.\n * @param[in] dev : Structure instance of bme680_dev.\n *\n * @return Result of API execution status\n * @retval zero -> Success / +ve value -> Warning / -ve value -> Error\n */\nint8_t bme680_get_sensor_data( struct bme680_field_data *data, struct bme680_dev *dev );\n\n/*!\n * @brief This API is used to set the oversampling, filter and T,P,H, gas selection\n * settings in the sensor.\n *\n * @param[in] dev : Structure instance of bme680_dev.\n * @param[in] desired_settings : Variable used to select the settings which\n * are to be set in the sensor.\n *\n *\t Macros\t                   |  Functionality\n *---------------------------------|----------------------------------------------\n *\tBME680_OST_SEL             |    To set temperature oversampling.\n *\tBME680_OSP_SEL             |    To set pressure oversampling.\n *\tBME680_OSH_SEL             |    To set humidity oversampling.\n *\tBME680_GAS_MEAS_SEL        |    To set gas measurement setting.\n *\tBME680_FILTER_SEL          |    To set filter setting.\n *\tBME680_HCNTRL_SEL          |    To set humidity control setting.\n *\tBME680_RUN_GAS_SEL         |    To set run gas setting.\n *\tBME680_NBCONV_SEL          |    To set NB conversion setting.\n *\tBME680_GAS_SENSOR_SEL      |    To set all gas sensor related settings\n *\n * @note : Below are the macros to be used by the user for selecting the\n * desired settings. User can do OR operation of these macros for configuring\n * multiple settings.\n *\n * @return Result of API execution status\n * @retval zero -> Success / +ve value -> Warning / -ve value -> Error.\n */\nint8_t bme680_set_sensor_settings( uint16_t desired_settings, struct bme680_dev *dev );\n\n/*!\n * @brief This API is used to get the oversampling, filter and T,P,H, gas selection\n * settings in the sensor.\n *\n * @param[in] dev : Structure instance of bme680_dev.\n * @param[in] desired_settings : Variable used to select the settings which\n * are to be get from the sensor.\n *\n * @return Result of API execution status\n * @retval zero -> Success / +ve value -> Warning / -ve value -> Error.\n */\nint8_t bme680_get_sensor_settings( uint16_t desired_settings, struct bme680_dev *dev );\n#ifdef __cplusplus\n}\n#endif /* End of CPP guard */\n#endif /* BME680_H_ */\n/** @}*/\n"
              },
              "objects": {
                "bme680.c": "#include \"bme680.h\"\n#include \"bme680_reg.h\"\n#include \"bme680_env.h\"\n\nstatic struct bme680_dev _BME680_DriverConfig = {0};\nstatic BME680_Config_t _BME680_PrivConfig;\nstatic uint16_t _BLE680_Meas_Delay_Ms = 0;\n\n\nstatic int8_t BME680_I2C_Write( uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len )\n{\n\tuint8_t status;\n\n\tuint8_t writeData[len + 1];\n\n\twriteData[0] = reg_addr;\n\tmemcpy( &writeData[1], reg_data, len );\n\n\treturn ATMO_I2C_MasterWrite( _BME680_PrivConfig.i2cInstance, dev_id, NULL, 0, writeData, len + 1, 0 ) == ATMO_I2C_Status_Success ? 0 : 1;\n}\n\nstatic int8_t BME680_I2C_Read( uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len )\n{\n\tATMO_I2C_Status_t status = ATMO_I2C_Status_Success;\n\tuint8_t currentReg = reg_addr;\n\n\tunsigned int i;\n\n\tstatus = ATMO_I2C_MasterRead( _BME680_PrivConfig.i2cInstance, dev_id,\n\t                              &reg_addr, 1, reg_data, len, 0 );\n\n\treturn ( status == ATMO_I2C_Status_Success ) ? 0 : 1;\n}\n\nBME680_Status_t BME680_Init( BME680_Config_t *config )\n{\n\tif ( config == NULL )\n\t{\n\t\treturn BME680_Status_Fail;\n\t}\n\n\tmemcpy( &_BME680_PrivConfig, config, sizeof( _BME680_PrivConfig ) );\n\n\tATMO_I2C_Peripheral_t i2cConfig;\n\ti2cConfig.operatingMode = ATMO_I2C_OperatingMode_Master;\n\ti2cConfig.baudRate = ATMO_I2C_BaudRate_Standard_Mode;\n\tATMO_I2C_SetConfiguration( config->i2cInstance, &i2cConfig );\n\n\tATMO_PLATFORM_DelayMilliseconds( 1000 );\n\n\tint8_t status;\n\tuint8_t sel_setting;\n\n\t_BME680_DriverConfig.dev_id = config->i2cAddr;\n\t_BME680_DriverConfig.intf = BME680_I2C_INTF;\n\t_BME680_DriverConfig.read = &BME680_I2C_Read;\n\t_BME680_DriverConfig.write = &BME680_I2C_Write;\n\t_BME680_DriverConfig.delay_ms = &ATMO_PLATFORM_DelayMilliseconds;\n\t_BME680_DriverConfig.amb_temp = 25;\n\n\tATMO_PLATFORM_DebugPrint( \"BME680 I2C Address: %02X\\r\\n\", _BME680_DriverConfig.dev_id );\n\n\tstatus = bme680_init( &_BME680_DriverConfig );\n\n\tif ( status != BME680_OK )\n\t{\n\t\tATMO_PLATFORM_DebugPrint( \"Error initializing BME680: %d\\r\\n\", status );\n\t\treturn BME680_Status_Fail;\n\t}\n\n\t_BME680_DriverConfig.tph_sett.os_hum = RTE_BME680_ENV_OS_HUM;\n\t_BME680_DriverConfig.tph_sett.os_pres = RTE_BME680_ENV_OS_PRES;\n\t_BME680_DriverConfig.tph_sett.os_temp = RTE_BME680_ENV_OS_TEMP;\n\t_BME680_DriverConfig.tph_sett.filter = RTE_BME680_ENV_FILTER_SIZE;\n\n\t_BME680_DriverConfig.gas_sett.run_gas = BME680_ENABLE_GAS_MEAS;\n\t_BME680_DriverConfig.gas_sett.heatr_temp = 320;\n\t_BME680_DriverConfig.gas_sett.heatr_dur = 150;\n\n\t_BME680_DriverConfig.power_mode = BME680_SLEEP_MODE;\n\n\tsel_setting = BME680_OST_SEL | BME680_OSP_SEL | BME680_OSH_SEL\n\t              | BME680_FILTER_SEL | BME680_GAS_SENSOR_SEL;\n\n\tstatus = bme680_set_sensor_settings( sel_setting, &_BME680_DriverConfig );\n\n\tif ( status != BME680_OK )\n\t{\n\t\tATMO_PLATFORM_DebugPrint( \"Error setting sensor settings\\r\\n\" );\n\t\treturn BME680_Status_Fail;\n\t}\n\n\tstatus = bme680_set_sensor_mode( &_BME680_DriverConfig );\n\n\tif ( status != BME680_OK )\n\t{\n\t\tATMO_PLATFORM_DebugPrint( \"Error setting sensor mode\\r\\n\" );\n\t\treturn BME680_Status_Fail;\n\t}\n\n\t// How long it takes between turning sensor on and getting a reading\n\tbme680_get_profile_dur( &_BLE680_Meas_Delay_Ms, &_BME680_DriverConfig );\n\n\tATMO_PLATFORM_DebugPrint( \"Meas Delay: %d\\r\\n\", _BLE680_Meas_Delay_Ms );\n\n\treturn 0;\n}\n\nstatic void _BME680_StartMeasurement()\n{\n\t// Turn sensor on to start measure\n\t_BME680_DriverConfig.power_mode = BME680_FORCED_MODE;\n\tbme680_set_sensor_mode( &_BME680_DriverConfig );\n\n\t// Wait for measurement to complete\n\tATMO_PLATFORM_DelayMilliseconds( _BLE680_Meas_Delay_Ms );\n}\n\nstatic void _BME680_Sleep()\n{\n\t// Go back to sleep\n\t_BME680_DriverConfig.power_mode = BME680_SLEEP_MODE;\n\tbme680_set_sensor_mode( &_BME680_DriverConfig );\n}\n\nBME680_Status_t BME680_GetTempData( float *tempC )\n{\n\t_BME680_StartMeasurement();\n\n\tstruct bme680_field_data data;\n\tint8_t retval = bme680_get_sensor_data( &data, &_BME680_DriverConfig );\n\n\tif ( retval != 0 )\n\t{\n\t\tATMO_PLATFORM_DebugPrint( \"Error getting sensor data! %d\\r\\n\", retval );\n\t\t*tempC = 0;\n\t}\n\telse\n\t{\n\t\t*tempC = data.temperature;\n\t}\n\n\t_BME680_Sleep();\n\treturn BME680_Status_Success;\n}\n\nBME680_Status_t BME680_GetPressure( float *pressureHpa )\n{\n\t_BME680_StartMeasurement();\n\n\tstruct bme680_field_data data;\n\tint8_t retval = bme680_get_sensor_data( &data, &_BME680_DriverConfig );\n\n\tif ( retval != 0 )\n\t{\n\t\tATMO_PLATFORM_DebugPrint( \"Error getting sensor data! %d\\r\\n\", retval );\n\t\t*pressureHpa = 0;\n\t}\n\telse\n\t{\n\t\t*pressureHpa = data.pressure;\n\t}\n\n\t_BME680_Sleep();\n\treturn BME680_Status_Success;\n}\n\nBME680_Status_t BME680_GetHumidity( float *humidity )\n{\n\t_BME680_StartMeasurement();\n\n\tstruct bme680_field_data data;\n\tint8_t retval = bme680_get_sensor_data( &data, &_BME680_DriverConfig );\n\n\tif ( retval != 0 )\n\t{\n\t\tATMO_PLATFORM_DebugPrint( \"Error getting sensor data! %d\\r\\n\", retval );\n\t\t*humidity = 0;\n\t}\n\telse\n\t{\n\t\t*humidity = data.humidity;\n\t}\n\n\t_BME680_Sleep();\n\treturn BME680_Status_Success;\n}\n\nBME680_Status_t BME680_GetGasRes( float *gas_resistance )\n{\n\t_BME680_StartMeasurement();\n\n\tstruct bme680_field_data data;\n\tint8_t retval = bme680_get_sensor_data( &data, &_BME680_DriverConfig );\n\n\tif ( retval != 0 )\n\t{\n\t\tATMO_PLATFORM_DebugPrint( \"Error getting sensor data! %d\\r\\n\", retval );\n\t\t*gas_resistance = 0;\n\t}\n\telse\n\t{\n\t\t*gas_resistance = data.gas_resistance;\n\t}\n\n\t_BME680_Sleep();\n\treturn BME680_Status_Success;\n}\n",
                "bme680_reg.c": "#include \"bme680_reg.h\"\n\nstatic int8_t get_calib_data( struct bme680_dev *dev );\nstatic int8_t set_gas_config( struct bme680_dev *dev );\nstatic int8_t get_gas_config( struct bme680_dev *dev );\nstatic uint8_t calc_heater_dur( uint16_t dur );\n\n#ifndef BME680_FLOAT_POINT_COMPENSATION\nstatic int16_t calc_temperature( uint32_t temp_adc, struct bme680_dev *dev );\nstatic uint32_t calc_pressure( uint32_t pres_adc, const struct bme680_dev *dev );\nstatic uint32_t calc_humidity( uint16_t hum_adc, const struct bme680_dev *dev );\nstatic uint32_t calc_gas_resistance( uint16_t gas_res_adc, uint8_t gas_range, const struct bme680_dev *dev );\nstatic uint8_t calc_heater_res( uint16_t temp, const struct bme680_dev *dev );\n\n#else\nstatic float calc_temperature( uint32_t temp_adc, struct bme680_dev *dev );\nstatic float calc_pressure( uint32_t pres_adc, const struct bme680_dev *dev );\nstatic float calc_humidity( uint16_t hum_adc, const struct bme680_dev *dev );\nstatic float calc_gas_resistance( uint16_t gas_res_adc, uint8_t gas_range, const struct bme680_dev *dev );\nstatic float calc_heater_res( uint16_t temp, const struct bme680_dev *dev );\n\n#endif\n\nstatic int8_t read_field_data( struct bme680_field_data *data, struct bme680_dev *dev );\nstatic int8_t set_mem_page( uint8_t reg_addr, struct bme680_dev *dev );\nstatic int8_t get_mem_page( struct bme680_dev *dev );\nstatic int8_t null_ptr_check( const struct bme680_dev *dev );\nstatic int8_t boundary_check( uint8_t *value, uint8_t min, uint8_t max, struct bme680_dev *dev );\n\nint8_t bme680_init( struct bme680_dev *dev )\n{\n\tint8_t rslt;\n\trslt = null_ptr_check( dev );\n\n\tif ( rslt == BME680_OK )\n\t{\n\t\trslt = bme680_soft_reset( dev );\n\n\t\tif ( rslt == BME680_OK )\n\t\t{\n\t\t\trslt = bme680_get_regs( BME680_CHIP_ID_ADDR, &dev->chip_id, 1, dev );\n\n\t\t\tif ( rslt == BME680_OK )\n\t\t\t{\n\t\t\t\tif ( dev->chip_id == BME680_CHIP_ID )\n\t\t\t\t{\n\t\t\t\t\trslt = get_calib_data( dev );\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\trslt = BME680_E_DEV_NOT_FOUND;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn rslt;\n}\n\nint8_t bme680_get_regs( uint8_t reg_addr, uint8_t *reg_data, uint16_t len, struct bme680_dev *dev )\n{\n\tint8_t rslt;\n\trslt = null_ptr_check( dev );\n\n\tif ( rslt == BME680_OK )\n\t{\n\t\tif ( dev->intf == BME680_SPI_INTF )\n\t\t{\n\t\t\trslt = set_mem_page( reg_addr, dev );\n\n\t\t\tif ( rslt == BME680_OK )\n\t\t\t{\n\t\t\t\treg_addr = reg_addr | BME680_SPI_RD_MSK;\n\t\t\t}\n\t\t}\n\n\t\tdev->com_rslt = dev->read( dev->dev_id, reg_addr, reg_data, len );\n\n\t\tif ( dev->com_rslt != 0 )\n\t\t{\n\t\t\trslt = BME680_E_COM_FAIL;\n\t\t}\n\t}\n\n\treturn rslt;\n}\nint8_t bme680_set_regs( const uint8_t *reg_addr, const uint8_t *reg_data, uint8_t len, struct bme680_dev *dev )\n{\n\tint8_t rslt;\n\tuint8_t tmp_buff[BME680_TMP_BUFFER_LENGTH] = { 0 };\n\tuint16_t index;\n\trslt = null_ptr_check( dev );\n\n\tif ( rslt == BME680_OK )\n\t{\n\t\tif ( ( len > 0 ) && ( len < BME680_TMP_BUFFER_LENGTH / 2 ) )\n\t\t{\n\t\t\tfor ( index = 0; index < len; index++ )\n\t\t\t{\n\t\t\t\tif ( dev->intf == BME680_SPI_INTF )\n\t\t\t\t{\n\t\t\t\t\trslt = set_mem_page( reg_addr[index], dev );\n\t\t\t\t\ttmp_buff[( 2 * index )] = reg_addr[index] & BME680_SPI_WR_MSK;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\ttmp_buff[( 2 * index )] = reg_addr[index];\n\t\t\t\t}\n\n\t\t\t\ttmp_buff[( 2 * index ) + 1] = reg_data[index];\n\t\t\t}\n\n\t\t\tif ( rslt == BME680_OK )\n\t\t\t{\n\t\t\t\tdev->com_rslt = dev->write( dev->dev_id, tmp_buff[0], &tmp_buff[1], ( 2 * len ) - 1 );\n\n\t\t\t\tif ( dev->com_rslt != 0 )\n\t\t\t\t{\n\t\t\t\t\trslt = BME680_E_COM_FAIL;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\trslt = BME680_E_INVALID_LENGTH;\n\t\t}\n\t}\n\n\treturn rslt;\n}\n\nint8_t bme680_soft_reset( struct bme680_dev *dev )\n{\n\tint8_t rslt;\n\tuint8_t reg_addr = BME680_SOFT_RESET_ADDR;\n\tuint8_t soft_rst_cmd = BME680_SOFT_RESET_CMD;\n\n\trslt = null_ptr_check( dev );\n\n\tif ( rslt == BME680_OK )\n\t{\n\t\tif ( dev->intf == BME680_SPI_INTF )\n\t\t{\n\t\t\trslt = get_mem_page( dev );\n\t\t}\n\n\t\tif ( rslt == BME680_OK )\n\t\t{\n\t\t\trslt = bme680_set_regs( &reg_addr, &soft_rst_cmd, 1, dev );\n\t\t\tdev->delay_ms( BME680_RESET_PERIOD );\n\n\t\t\tif ( rslt == BME680_OK )\n\t\t\t{\n\t\t\t\tif ( dev->intf == BME680_SPI_INTF )\n\t\t\t\t{\n\t\t\t\t\trslt = get_mem_page( dev );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn rslt;\n}\n\nint8_t bme680_set_sensor_settings( uint16_t desired_settings, struct bme680_dev *dev )\n{\n\tint8_t rslt;\n\tuint8_t reg_addr;\n\tuint8_t data = 0;\n\tuint8_t count = 0;\n\tuint8_t reg_array[BME680_REG_BUFFER_LENGTH] = { 0 };\n\tuint8_t data_array[BME680_REG_BUFFER_LENGTH] = { 0 };\n\tuint8_t intended_power_mode = dev->power_mode;\n\trslt = null_ptr_check( dev );\n\n\tif ( rslt == BME680_OK )\n\t{\n\t\tif ( desired_settings & BME680_GAS_MEAS_SEL )\n\t\t{\n\t\t\trslt = set_gas_config( dev );\n\t\t}\n\n\t\tdev->power_mode = BME680_SLEEP_MODE;\n\n\t\tif ( rslt == BME680_OK )\n\t\t{\n\t\t\trslt = bme680_set_sensor_mode( dev );\n\t\t}\n\n\t\tif ( desired_settings & BME680_FILTER_SEL )\n\t\t{\n\t\t\trslt = boundary_check( &dev->tph_sett.filter, BME680_FILTER_SIZE_0, BME680_FILTER_SIZE_127, dev );\n\t\t\treg_addr = BME680_CONF_ODR_FILT_ADDR;\n\n\t\t\tif ( rslt == BME680_OK )\n\t\t\t{\n\t\t\t\trslt = bme680_get_regs( reg_addr, &data, 1, dev );\n\t\t\t}\n\n\t\t\tif ( desired_settings & BME680_FILTER_SEL )\n\t\t\t{\n\t\t\t\tdata = BME680_SET_BITS( data, BME680_FILTER, dev->tph_sett.filter );\n\t\t\t}\n\n\t\t\treg_array[count] = reg_addr;\n\t\t\tdata_array[count] = data;\n\t\t\tcount++;\n\t\t}\n\n\t\tif ( desired_settings & BME680_HCNTRL_SEL )\n\t\t{\n\t\t\trslt = boundary_check( &dev->gas_sett.heatr_ctrl, BME680_ENABLE_HEATER,\n\t\t\t                       BME680_DISABLE_HEATER, dev );\n\t\t\treg_addr = BME680_CONF_HEAT_CTRL_ADDR;\n\n\t\t\tif ( rslt == BME680_OK )\n\t\t\t{\n\t\t\t\trslt = bme680_get_regs( reg_addr, &data, 1, dev );\n\t\t\t}\n\n\t\t\tdata = BME680_SET_BITS_POS_0( data, BME680_HCTRL, dev->gas_sett.heatr_ctrl );\n\n\t\t\treg_array[count] = reg_addr;\n\t\t\tdata_array[count] = data;\n\t\t\tcount++;\n\t\t}\n\n\t\tif ( desired_settings & ( BME680_OST_SEL | BME680_OSP_SEL ) )\n\t\t{\n\t\t\trslt = boundary_check( &dev->tph_sett.os_temp, BME680_OS_NONE, BME680_OS_16X, dev );\n\t\t\treg_addr = BME680_CONF_T_P_MODE_ADDR;\n\n\t\t\tif ( rslt == BME680_OK )\n\t\t\t{\n\t\t\t\trslt = bme680_get_regs( reg_addr, &data, 1, dev );\n\t\t\t}\n\n\t\t\tif ( desired_settings & BME680_OST_SEL )\n\t\t\t{\n\t\t\t\tdata = BME680_SET_BITS( data, BME680_OST, dev->tph_sett.os_temp );\n\t\t\t}\n\n\t\t\tif ( desired_settings & BME680_OSP_SEL )\n\t\t\t{\n\t\t\t\tdata = BME680_SET_BITS( data, BME680_OSP, dev->tph_sett.os_pres );\n\t\t\t}\n\n\t\t\treg_array[count] = reg_addr;\n\t\t\tdata_array[count] = data;\n\t\t\tcount++;\n\t\t}\n\n\t\tif ( desired_settings & BME680_OSH_SEL )\n\t\t{\n\t\t\trslt = boundary_check( &dev->tph_sett.os_hum, BME680_OS_NONE, BME680_OS_16X, dev );\n\t\t\treg_addr = BME680_CONF_OS_H_ADDR;\n\n\t\t\tif ( rslt == BME680_OK )\n\t\t\t{\n\t\t\t\trslt = bme680_get_regs( reg_addr, &data, 1, dev );\n\t\t\t}\n\n\t\t\tdata = BME680_SET_BITS_POS_0( data, BME680_OSH, dev->tph_sett.os_hum );\n\n\t\t\treg_array[count] = reg_addr;\n\t\t\tdata_array[count] = data;\n\t\t\tcount++;\n\t\t}\n\n\t\tif ( desired_settings & ( BME680_RUN_GAS_SEL | BME680_NBCONV_SEL ) )\n\t\t{\n\t\t\trslt = boundary_check( &dev->gas_sett.run_gas, BME680_RUN_GAS_DISABLE,\n\t\t\t                       BME680_RUN_GAS_ENABLE, dev );\n\n\t\t\tif ( rslt == BME680_OK )\n\t\t\t{\n\t\t\t\trslt = boundary_check( &dev->gas_sett.nb_conv, BME680_NBCONV_MIN,\n\t\t\t\t                       BME680_NBCONV_MAX, dev );\n\t\t\t}\n\n\t\t\treg_addr = BME680_CONF_ODR_RUN_GAS_NBC_ADDR;\n\n\t\t\tif ( rslt == BME680_OK )\n\t\t\t{\n\t\t\t\trslt = bme680_get_regs( reg_addr, &data, 1, dev );\n\t\t\t}\n\n\t\t\tif ( desired_settings & BME680_RUN_GAS_SEL )\n\t\t\t{\n\t\t\t\tdata = BME680_SET_BITS( data, BME680_RUN_GAS, dev->gas_sett.run_gas );\n\t\t\t}\n\n\t\t\tif ( desired_settings & BME680_NBCONV_SEL )\n\t\t\t{\n\t\t\t\tdata = BME680_SET_BITS_POS_0( data, BME680_NBCONV, dev->gas_sett.nb_conv );\n\t\t\t}\n\n\t\t\treg_array[count] = reg_addr;\n\t\t\tdata_array[count] = data;\n\t\t\tcount++;\n\t\t}\n\n\t\tif ( rslt == BME680_OK )\n\t\t{\n\t\t\trslt = bme680_set_regs( reg_array, data_array, count, dev );\n\t\t}\n\n\t\tdev->power_mode = intended_power_mode;\n\t}\n\n\treturn rslt;\n}\n\nint8_t bme680_get_sensor_settings( uint16_t desired_settings, struct bme680_dev *dev )\n{\n\tint8_t rslt;\n\tuint8_t reg_addr = BME680_CONF_HEAT_CTRL_ADDR;\n\tuint8_t data_array[BME680_REG_BUFFER_LENGTH] = { 0 };\n\n\trslt = null_ptr_check( dev );\n\n\tif ( rslt == BME680_OK )\n\t{\n\t\trslt = bme680_get_regs( reg_addr, data_array, BME680_REG_BUFFER_LENGTH, dev );\n\n\t\tif ( rslt == BME680_OK )\n\t\t{\n\t\t\tif ( desired_settings & BME680_GAS_MEAS_SEL )\n\t\t\t{\n\t\t\t\trslt = get_gas_config( dev );\n\t\t\t}\n\n\t\t\tif ( desired_settings & BME680_FILTER_SEL )\n\t\t\t\tdev->tph_sett.filter = BME680_GET_BITS( data_array[BME680_REG_FILTER_INDEX],\n\t\t\t\t                                        BME680_FILTER );\n\n\t\t\tif ( desired_settings & ( BME680_OST_SEL | BME680_OSP_SEL ) )\n\t\t\t{\n\t\t\t\tdev->tph_sett.os_temp = BME680_GET_BITS( data_array[BME680_REG_TEMP_INDEX], BME680_OST );\n\t\t\t\tdev->tph_sett.os_pres = BME680_GET_BITS( data_array[BME680_REG_PRES_INDEX], BME680_OSP );\n\t\t\t}\n\n\t\t\tif ( desired_settings & BME680_OSH_SEL )\n\t\t\t\tdev->tph_sett.os_hum = BME680_GET_BITS_POS_0( data_array[BME680_REG_HUM_INDEX],\n\t\t\t\t                       BME680_OSH );\n\n\t\t\tif ( desired_settings & BME680_HCNTRL_SEL )\n\t\t\t\tdev->gas_sett.heatr_ctrl = BME680_GET_BITS_POS_0( data_array[BME680_REG_HCTRL_INDEX],\n\t\t\t\t                           BME680_HCTRL );\n\n\t\t\tif ( desired_settings & ( BME680_RUN_GAS_SEL | BME680_NBCONV_SEL ) )\n\t\t\t{\n\t\t\t\tdev->gas_sett.nb_conv = BME680_GET_BITS_POS_0( data_array[BME680_REG_NBCONV_INDEX],\n\t\t\t\t                        BME680_NBCONV );\n\t\t\t\tdev->gas_sett.run_gas = BME680_GET_BITS( data_array[BME680_REG_RUN_GAS_INDEX],\n\t\t\t\t                        BME680_RUN_GAS );\n\t\t\t}\n\t\t}\n\t}\n\telse\n\t{\n\t\trslt = BME680_E_NULL_PTR;\n\t}\n\n\treturn rslt;\n}\n\nint8_t bme680_set_sensor_mode( struct bme680_dev *dev )\n{\n\tint8_t rslt;\n\tuint8_t tmp_pow_mode;\n\tuint8_t pow_mode = 0;\n\tuint8_t reg_addr = BME680_CONF_T_P_MODE_ADDR;\n\n\trslt = null_ptr_check( dev );\n\n\tif ( rslt == BME680_OK )\n\t{\n\t\tdo\n\t\t{\n\t\t\trslt = bme680_get_regs( BME680_CONF_T_P_MODE_ADDR, &tmp_pow_mode, 1, dev );\n\n\t\t\tif ( rslt == BME680_OK )\n\t\t\t{\n\t\t\t\tpow_mode = ( tmp_pow_mode & BME680_MODE_MSK );\n\n\t\t\t\tif ( pow_mode != BME680_SLEEP_MODE )\n\t\t\t\t{\n\t\t\t\t\ttmp_pow_mode = tmp_pow_mode & ( ~BME680_MODE_MSK );\n\t\t\t\t\trslt = bme680_set_regs( &reg_addr, &tmp_pow_mode, 1, dev );\n\t\t\t\t\tdev->delay_ms( BME680_POLL_PERIOD_MS );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\twhile ( pow_mode != BME680_SLEEP_MODE );\n\n\t\tif ( dev->power_mode != BME680_SLEEP_MODE )\n\t\t{\n\t\t\ttmp_pow_mode = ( tmp_pow_mode & ~BME680_MODE_MSK ) | ( dev->power_mode & BME680_MODE_MSK );\n\n\t\t\tif ( rslt == BME680_OK )\n\t\t\t{\n\t\t\t\trslt = bme680_set_regs( &reg_addr, &tmp_pow_mode, 1, dev );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn rslt;\n}\n\nint8_t bme680_get_sensor_mode( struct bme680_dev *dev )\n{\n\tint8_t rslt;\n\tuint8_t mode;\n\n\trslt = null_ptr_check( dev );\n\n\tif ( rslt == BME680_OK )\n\t{\n\t\trslt = bme680_get_regs( BME680_CONF_T_P_MODE_ADDR, &mode, 1, dev );\n\t\tdev->power_mode = mode & BME680_MODE_MSK;\n\t}\n\n\treturn rslt;\n}\n\nvoid bme680_set_profile_dur( uint16_t duration, struct bme680_dev *dev )\n{\n\tuint32_t tph_dur;\n\tuint32_t meas_cycles;\n\tuint8_t os_to_meas_cycles[6] = {0, 1, 2, 4, 8, 16};\n\n\tmeas_cycles = os_to_meas_cycles[dev->tph_sett.os_temp];\n\tmeas_cycles += os_to_meas_cycles[dev->tph_sett.os_pres];\n\tmeas_cycles += os_to_meas_cycles[dev->tph_sett.os_hum];\n\n\ttph_dur = meas_cycles * UINT32_C( 1963 );\n\ttph_dur += UINT32_C( 477 * 4 );\n\ttph_dur += UINT32_C( 477 * 5 );\n\ttph_dur += UINT32_C( 500 );\n\ttph_dur /= UINT32_C( 1000 );\n\n\ttph_dur += UINT32_C( 1 );\n\tdev->gas_sett.heatr_dur = duration - ( uint16_t ) tph_dur;\n}\n\nvoid bme680_get_profile_dur( uint16_t *duration, const struct bme680_dev *dev )\n{\n\tuint32_t tph_dur;\n\tuint32_t meas_cycles;\n\tuint8_t os_to_meas_cycles[6] = {0, 1, 2, 4, 8, 16};\n\n\tmeas_cycles = os_to_meas_cycles[dev->tph_sett.os_temp];\n\tmeas_cycles += os_to_meas_cycles[dev->tph_sett.os_pres];\n\tmeas_cycles += os_to_meas_cycles[dev->tph_sett.os_hum];\n\n\ttph_dur = meas_cycles * UINT32_C( 1963 );\n\ttph_dur += UINT32_C( 477 * 4 );\n\ttph_dur += UINT32_C( 477 * 5 );\n\ttph_dur += UINT32_C( 500 );\n\ttph_dur /= UINT32_C( 1000 );\n\n\ttph_dur += UINT32_C( 1 );\n\n\t*duration = ( uint16_t ) tph_dur;\n\n\tif ( dev->gas_sett.run_gas )\n\t{\n\t\t*duration += dev->gas_sett.heatr_dur;\n\t}\n}\n\nint8_t bme680_get_sensor_data( struct bme680_field_data *data, struct bme680_dev *dev )\n{\n\tint8_t rslt;\n\n\trslt = null_ptr_check( dev );\n\n\tif ( rslt == BME680_OK )\n\t{\n\t\trslt = read_field_data( data, dev );\n\n\t\tif ( rslt == BME680_OK )\n\t\t{\n\t\t\tif ( data->status & BME680_NEW_DATA_MSK )\n\t\t\t{\n\t\t\t\tdev->new_fields = 1;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tdev->new_fields = 0;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn rslt;\n}\n\nstatic int8_t get_calib_data( struct bme680_dev *dev )\n{\n\tint8_t rslt;\n\tuint8_t coeff_array[BME680_COEFF_SIZE] = { 0 };\n\tuint8_t temp_var = 0;\n\trslt = null_ptr_check( dev );\n\n\tif ( rslt == BME680_OK )\n\t{\n\t\trslt = bme680_get_regs( BME680_COEFF_ADDR1, coeff_array, BME680_COEFF_ADDR1_LEN, dev );\n\n\t\tif ( rslt == BME680_OK )\n\t\t\trslt = bme680_get_regs( BME680_COEFF_ADDR2, &coeff_array[BME680_COEFF_ADDR1_LEN]\n\t\t\t                        , BME680_COEFF_ADDR2_LEN, dev );\n\n\t\tdev->calib.par_t1 = ( uint16_t ) ( BME680_CONCAT_BYTES( coeff_array[BME680_T1_MSB_REG],\n\t\t                                   coeff_array[BME680_T1_LSB_REG] ) );\n\t\tdev->calib.par_t2 = ( int16_t ) ( BME680_CONCAT_BYTES( coeff_array[BME680_T2_MSB_REG],\n\t\t                                  coeff_array[BME680_T2_LSB_REG] ) );\n\t\tdev->calib.par_t3 = ( int8_t ) ( coeff_array[BME680_T3_REG] );\n\n\t\tdev->calib.par_p1 = ( uint16_t ) ( BME680_CONCAT_BYTES( coeff_array[BME680_P1_MSB_REG],\n\t\t                                   coeff_array[BME680_P1_LSB_REG] ) );\n\t\tdev->calib.par_p2 = ( int16_t ) ( BME680_CONCAT_BYTES( coeff_array[BME680_P2_MSB_REG],\n\t\t                                  coeff_array[BME680_P2_LSB_REG] ) );\n\t\tdev->calib.par_p3 = ( int8_t ) coeff_array[BME680_P3_REG];\n\t\tdev->calib.par_p4 = ( int16_t ) ( BME680_CONCAT_BYTES( coeff_array[BME680_P4_MSB_REG],\n\t\t                                  coeff_array[BME680_P4_LSB_REG] ) );\n\t\tdev->calib.par_p5 = ( int16_t ) ( BME680_CONCAT_BYTES( coeff_array[BME680_P5_MSB_REG],\n\t\t                                  coeff_array[BME680_P5_LSB_REG] ) );\n\t\tdev->calib.par_p6 = ( int8_t ) ( coeff_array[BME680_P6_REG] );\n\t\tdev->calib.par_p7 = ( int8_t ) ( coeff_array[BME680_P7_REG] );\n\t\tdev->calib.par_p8 = ( int16_t ) ( BME680_CONCAT_BYTES( coeff_array[BME680_P8_MSB_REG],\n\t\t                                  coeff_array[BME680_P8_LSB_REG] ) );\n\t\tdev->calib.par_p9 = ( int16_t ) ( BME680_CONCAT_BYTES( coeff_array[BME680_P9_MSB_REG],\n\t\t                                  coeff_array[BME680_P9_LSB_REG] ) );\n\t\tdev->calib.par_p10 = ( uint8_t ) ( coeff_array[BME680_P10_REG] );\n\n\t\tdev->calib.par_h1 = ( uint16_t ) ( ( ( uint16_t ) coeff_array[BME680_H1_MSB_REG] << BME680_HUM_REG_SHIFT_VAL )\n\t\t                                   | ( coeff_array[BME680_H1_LSB_REG] & BME680_BIT_H1_DATA_MSK ) );\n\t\tdev->calib.par_h2 = ( uint16_t ) ( ( ( uint16_t ) coeff_array[BME680_H2_MSB_REG] << BME680_HUM_REG_SHIFT_VAL )\n\t\t                                   | ( ( coeff_array[BME680_H2_LSB_REG] ) >> BME680_HUM_REG_SHIFT_VAL ) );\n\t\tdev->calib.par_h3 = ( int8_t ) coeff_array[BME680_H3_REG];\n\t\tdev->calib.par_h4 = ( int8_t ) coeff_array[BME680_H4_REG];\n\t\tdev->calib.par_h5 = ( int8_t ) coeff_array[BME680_H5_REG];\n\t\tdev->calib.par_h6 = ( uint8_t ) coeff_array[BME680_H6_REG];\n\t\tdev->calib.par_h7 = ( int8_t ) coeff_array[BME680_H7_REG];\n\n\t\tdev->calib.par_gh1 = ( int8_t ) coeff_array[BME680_GH1_REG];\n\t\tdev->calib.par_gh2 = ( int16_t ) ( BME680_CONCAT_BYTES( coeff_array[BME680_GH2_MSB_REG],\n\t\t                                   coeff_array[BME680_GH2_LSB_REG] ) );\n\t\tdev->calib.par_gh3 = ( int8_t ) coeff_array[BME680_GH3_REG];\n\n\t\tif ( rslt == BME680_OK )\n\t\t{\n\t\t\trslt = bme680_get_regs( BME680_ADDR_RES_HEAT_RANGE_ADDR, &temp_var, 1, dev );\n\n\t\t\tdev->calib.res_heat_range = ( ( temp_var & BME680_RHRANGE_MSK ) / 16 );\n\n\t\t\tif ( rslt == BME680_OK )\n\t\t\t{\n\t\t\t\trslt = bme680_get_regs( BME680_ADDR_RES_HEAT_VAL_ADDR, &temp_var, 1, dev );\n\n\t\t\t\tdev->calib.res_heat_val = ( int8_t ) temp_var;\n\n\t\t\t\tif ( rslt == BME680_OK )\n\t\t\t\t{\n\t\t\t\t\trslt = bme680_get_regs( BME680_ADDR_RANGE_SW_ERR_ADDR, &temp_var, 1, dev );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tdev->calib.range_sw_err = ( ( int8_t ) temp_var & ( int8_t ) BME680_RSERROR_MSK ) / 16;\n\t}\n\n\treturn rslt;\n}\n\nstatic int8_t set_gas_config( struct bme680_dev *dev )\n{\n\tint8_t rslt;\n\n\trslt = null_ptr_check( dev );\n\n\tif ( rslt == BME680_OK )\n\t{\n\n\t\tuint8_t reg_addr[2] = {0};\n\t\tuint8_t reg_data[2] = {0};\n\n\t\tif ( dev->power_mode == BME680_FORCED_MODE )\n\t\t{\n\t\t\treg_addr[0] = BME680_RES_HEAT0_ADDR;\n\t\t\treg_data[0] = calc_heater_res( dev->gas_sett.heatr_temp, dev );\n\t\t\treg_addr[1] = BME680_GAS_WAIT0_ADDR;\n\t\t\treg_data[1] = calc_heater_dur( dev->gas_sett.heatr_dur );\n\t\t\tdev->gas_sett.nb_conv = 0;\n\t\t}\n\t\telse\n\t\t{\n\t\t\trslt = BME680_W_DEFINE_PWR_MODE;\n\t\t}\n\n\t\tif ( rslt == BME680_OK )\n\t\t{\n\t\t\trslt = bme680_set_regs( reg_addr, reg_data, 2, dev );\n\t\t}\n\t}\n\n\treturn rslt;\n}\n\nstatic int8_t get_gas_config( struct bme680_dev *dev )\n{\n\tint8_t rslt;\n\tuint8_t reg_addr1 = BME680_ADDR_SENS_CONF_START;\n\tuint8_t reg_addr2 = BME680_ADDR_GAS_CONF_START;\n\tuint8_t reg_data = 0;\n\n\trslt = null_ptr_check( dev );\n\n\tif ( rslt == BME680_OK )\n\t{\n\t\tif ( BME680_SPI_INTF == dev->intf )\n\t\t{\n\t\t\trslt = set_mem_page( reg_addr1, dev );\n\t\t}\n\n\t\tif ( rslt == BME680_OK )\n\t\t{\n\t\t\trslt = bme680_get_regs( reg_addr1, &reg_data, 1, dev );\n\n\t\t\tif ( rslt == BME680_OK )\n\t\t\t{\n\t\t\t\tdev->gas_sett.heatr_temp = reg_data;\n\t\t\t\trslt = bme680_get_regs( reg_addr2, &reg_data, 1, dev );\n\n\t\t\t\tif ( rslt == BME680_OK )\n\t\t\t\t{\n\t\t\t\t\tdev->gas_sett.heatr_dur = reg_data;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn rslt;\n}\n\n#ifndef BME680_FLOAT_POINT_COMPENSATION\n\nstatic int16_t calc_temperature( uint32_t temp_adc, struct bme680_dev *dev )\n{\n\tint64_t var1;\n\tint64_t var2;\n\tint64_t var3;\n\tint16_t calc_temp;\n\n\tvar1 = ( ( int32_t ) temp_adc >> 3 ) - ( ( int32_t ) dev->calib.par_t1 << 1 );\n\tvar2 = ( var1 * ( int32_t ) dev->calib.par_t2 ) >> 11;\n\tvar3 = ( ( var1 >> 1 ) * ( var1 >> 1 ) ) >> 12;\n\tvar3 = ( ( var3 ) * ( ( int32_t ) dev->calib.par_t3 << 4 ) ) >> 14;\n\tdev->calib.t_fine = ( int32_t ) ( var2 + var3 );\n\tcalc_temp = ( int16_t ) ( ( ( dev->calib.t_fine * 5 ) + 128 ) >> 8 );\n\n\treturn calc_temp;\n}\n\nstatic uint32_t calc_pressure( uint32_t pres_adc, const struct bme680_dev *dev )\n{\n\tint32_t var1 = 0;\n\tint32_t var2 = 0;\n\tint32_t var3 = 0;\n\tint32_t pressure_comp = 0;\n\n\tvar1 = ( ( ( int32_t )dev->calib.t_fine ) >> 1 ) - 64000;\n\tvar2 = ( ( ( ( var1 >> 2 ) * ( var1 >> 2 ) ) >> 11 ) *\n\t         ( int32_t )dev->calib.par_p6 ) >> 2;\n\tvar2 = var2 + ( ( var1 * ( int32_t )dev->calib.par_p5 ) << 1 );\n\tvar2 = ( var2 >> 2 ) + ( ( int32_t )dev->calib.par_p4 << 16 );\n\tvar1 = ( ( ( ( ( var1 >> 2 ) * ( var1 >> 2 ) ) >> 13 ) *\n\t           ( ( int32_t )dev->calib.par_p3 << 5 ) ) >> 3 ) +\n\t       ( ( ( int32_t )dev->calib.par_p2 * var1 ) >> 1 );\n\tvar1 = var1 >> 18;\n\tvar1 = ( ( 32768 + var1 ) * ( int32_t )dev->calib.par_p1 ) >> 15;\n\tpressure_comp = 1048576 - pres_adc;\n\tpressure_comp = ( int32_t )( ( pressure_comp - ( var2 >> 12 ) ) * ( ( uint32_t )3125 ) );\n\n\tif ( pressure_comp >= BME680_MAX_OVERFLOW_VAL )\n\t{\n\t\tpressure_comp = ( ( pressure_comp / ( uint32_t )var1 ) << 1 );\n\t}\n\telse\n\t{\n\t\tpressure_comp = ( ( pressure_comp << 1 ) / ( uint32_t )var1 );\n\t}\n\n\tvar1 = ( ( int32_t )dev->calib.par_p9 * ( int32_t )( ( ( pressure_comp >> 3 ) *\n\t         ( pressure_comp >> 3 ) ) >> 13 ) ) >> 12;\n\tvar2 = ( ( int32_t )( pressure_comp >> 2 ) *\n\t         ( int32_t )dev->calib.par_p8 ) >> 13;\n\tvar3 = ( ( int32_t )( pressure_comp >> 8 ) * ( int32_t )( pressure_comp >> 8 ) *\n\t         ( int32_t )( pressure_comp >> 8 ) *\n\t         ( int32_t )dev->calib.par_p10 ) >> 17;\n\n\tpressure_comp = ( int32_t )( pressure_comp ) + ( ( var1 + var2 + var3 +\n\t                ( ( int32_t )dev->calib.par_p7 << 7 ) ) >> 4 );\n\n\treturn ( uint32_t )pressure_comp;\n\n}\n\nstatic uint32_t calc_humidity( uint16_t hum_adc, const struct bme680_dev *dev )\n{\n\tint32_t var1;\n\tint32_t var2;\n\tint32_t var3;\n\tint32_t var4;\n\tint32_t var5;\n\tint32_t var6;\n\tint32_t temp_scaled;\n\tint32_t calc_hum;\n\n\ttemp_scaled = ( ( ( int32_t ) dev->calib.t_fine * 5 ) + 128 ) >> 8;\n\tvar1 = ( int32_t ) ( hum_adc - ( ( int32_t ) ( ( int32_t ) dev->calib.par_h1 * 16 ) ) )\n\t       - ( ( ( temp_scaled * ( int32_t ) dev->calib.par_h3 ) / ( ( int32_t ) 100 ) ) >> 1 );\n\tvar2 = ( ( int32_t ) dev->calib.par_h2\n\t         * ( ( ( temp_scaled * ( int32_t ) dev->calib.par_h4 ) / ( ( int32_t ) 100 ) )\n\t             + ( ( ( temp_scaled * ( ( temp_scaled * ( int32_t ) dev->calib.par_h5 ) / ( ( int32_t ) 100 ) ) ) >> 6 )\n\t                 / ( ( int32_t ) 100 ) ) + ( int32_t ) ( 1 << 14 ) ) ) >> 10;\n\tvar3 = var1 * var2;\n\tvar4 = ( int32_t ) dev->calib.par_h6 << 7;\n\tvar4 = ( ( var4 ) + ( ( temp_scaled * ( int32_t ) dev->calib.par_h7 ) / ( ( int32_t ) 100 ) ) ) >> 4;\n\tvar5 = ( ( var3 >> 14 ) * ( var3 >> 14 ) ) >> 10;\n\tvar6 = ( var4 * var5 ) >> 1;\n\tcalc_hum = ( ( ( var3 + var6 ) >> 10 ) * ( ( int32_t ) 1000 ) ) >> 12;\n\n\tif ( calc_hum > 100000 )\n\t{\n\t\tcalc_hum = 100000;\n\t}\n\telse if ( calc_hum < 0 )\n\t{\n\t\tcalc_hum = 0;\n\t}\n\n\treturn ( uint32_t ) calc_hum;\n}\n\nstatic uint32_t calc_gas_resistance( uint16_t gas_res_adc, uint8_t gas_range, const struct bme680_dev *dev )\n{\n\tint64_t var1;\n\tuint64_t var2;\n\tint64_t var3;\n\tuint32_t calc_gas_res;\n\tuint32_t lookupTable1[16] = { UINT32_C( 2147483647 ), UINT32_C( 2147483647 ), UINT32_C( 2147483647 ), UINT32_C( 2147483647 ),\n\t                              UINT32_C( 2147483647 ), UINT32_C( 2126008810 ), UINT32_C( 2147483647 ), UINT32_C( 2130303777 ),\n\t                              UINT32_C( 2147483647 ), UINT32_C( 2147483647 ), UINT32_C( 2143188679 ), UINT32_C( 2136746228 ),\n\t                              UINT32_C( 2147483647 ), UINT32_C( 2126008810 ), UINT32_C( 2147483647 ), UINT32_C( 2147483647 )\n\t                            };\n\tuint32_t lookupTable2[16] = { UINT32_C( 4096000000 ), UINT32_C( 2048000000 ), UINT32_C( 1024000000 ), UINT32_C( 512000000 ),\n\t                              UINT32_C( 255744255 ), UINT32_C( 127110228 ), UINT32_C( 64000000 ), UINT32_C( 32258064 ), UINT32_C( 16016016 ),\n\t                              UINT32_C( 8000000 ), UINT32_C( 4000000 ), UINT32_C( 2000000 ), UINT32_C( 1000000 ), UINT32_C( 500000 ),\n\t                              UINT32_C( 250000 ), UINT32_C( 125000 )\n\t                            };\n\n\tvar1 = ( int64_t ) ( ( 1340 + ( 5 * ( int64_t ) dev->calib.range_sw_err ) ) *\n\t                     ( ( int64_t ) lookupTable1[gas_range] ) ) >> 16;\n\tvar2 = ( ( ( int64_t ) ( ( int64_t ) gas_res_adc << 15 ) - ( int64_t ) ( 16777216 ) ) + var1 );\n\tvar3 = ( ( ( int64_t ) lookupTable2[gas_range] * ( int64_t ) var1 ) >> 9 );\n\tcalc_gas_res = ( uint32_t ) ( ( var3 + ( ( int64_t ) var2 >> 1 ) ) / ( int64_t ) var2 );\n\n\treturn calc_gas_res;\n}\n\nstatic uint8_t calc_heater_res( uint16_t temp, const struct bme680_dev *dev )\n{\n\tuint8_t heatr_res;\n\tint32_t var1;\n\tint32_t var2;\n\tint32_t var3;\n\tint32_t var4;\n\tint32_t var5;\n\tint32_t heatr_res_x100;\n\n\tif ( temp > 400 )\n\t{\n\t\ttemp = 400;\n\t}\n\n\tvar1 = ( ( ( int32_t ) dev->amb_temp * dev->calib.par_gh3 ) / 1000 ) * 256;\n\tvar2 = ( dev->calib.par_gh1 + 784 ) * ( ( ( ( ( dev->calib.par_gh2 + 154009 ) * temp * 5 ) / 100 ) + 3276800 ) / 10 );\n\tvar3 = var1 + ( var2 / 2 );\n\tvar4 = ( var3 / ( dev->calib.res_heat_range + 4 ) );\n\tvar5 = ( 131 * dev->calib.res_heat_val ) + 65536;\n\theatr_res_x100 = ( int32_t ) ( ( ( var4 / var5 ) - 250 ) * 34 );\n\theatr_res = ( uint8_t ) ( ( heatr_res_x100 + 50 ) / 100 );\n\n\treturn heatr_res;\n}\n\n#else\n\nstatic float calc_temperature( uint32_t temp_adc, struct bme680_dev *dev )\n{\n\tfloat var1 = 0;\n\tfloat var2 = 0;\n\tfloat calc_temp = 0;\n\n\tvar1  = ( ( ( ( float )temp_adc / 16384.0f ) - ( ( float )dev->calib.par_t1 / 1024.0f ) )\n\t          * ( ( float )dev->calib.par_t2 ) );\n\n\tvar2  = ( ( ( ( ( float )temp_adc / 131072.0f ) - ( ( float )dev->calib.par_t1 / 8192.0f ) ) *\n\t            ( ( ( float )temp_adc / 131072.0f ) - ( ( float )dev->calib.par_t1 / 8192.0f ) ) ) *\n\t          ( ( float )dev->calib.par_t3 * 16.0f ) );\n\n\tdev->calib.t_fine = ( var1 + var2 );\n\n\tcalc_temp  = ( ( dev->calib.t_fine ) / 5120.0f );\n\n\treturn calc_temp;\n}\n\nstatic float calc_pressure( uint32_t pres_adc, const struct bme680_dev *dev )\n{\n\tfloat var1 = 0;\n\tfloat var2 = 0;\n\tfloat var3 = 0;\n\tfloat calc_pres = 0;\n\n\tvar1 = ( ( ( float )dev->calib.t_fine / 2.0f ) - 64000.0f );\n\tvar2 = var1 * var1 * ( ( ( float )dev->calib.par_p6 ) / ( 131072.0f ) );\n\tvar2 = var2 + ( var1 * ( ( float )dev->calib.par_p5 ) * 2.0f );\n\tvar2 = ( var2 / 4.0f ) + ( ( ( float )dev->calib.par_p4 ) * 65536.0f );\n\tvar1 = ( ( ( ( ( float )dev->calib.par_p3 * var1 * var1 ) / 16384.0f )\n\t           + ( ( float )dev->calib.par_p2 * var1 ) ) / 524288.0f );\n\tvar1 = ( ( 1.0f + ( var1 / 32768.0f ) ) * ( ( float )dev->calib.par_p1 ) );\n\tcalc_pres = ( 1048576.0f - ( ( float )pres_adc ) );\n\n\tif ( ( int )var1 != 0 )\n\t{\n\t\tcalc_pres = ( ( ( calc_pres - ( var2 / 4096.0f ) ) * 6250.0f ) / var1 );\n\t\tvar1 = ( ( ( float )dev->calib.par_p9 ) * calc_pres * calc_pres ) / 2147483648.0f;\n\t\tvar2 = calc_pres * ( ( ( float )dev->calib.par_p8 ) / 32768.0f );\n\t\tvar3 = ( ( calc_pres / 256.0f ) * ( calc_pres / 256.0f ) * ( calc_pres / 256.0f )\n\t\t         * ( dev->calib.par_p10 / 131072.0f ) );\n\t\tcalc_pres = ( calc_pres + ( var1 + var2 + var3 + ( ( float )dev->calib.par_p7 * 128.0f ) ) / 16.0f );\n\t}\n\telse\n\t{\n\t\tcalc_pres = 0;\n\t}\n\n\treturn calc_pres;\n}\n\nstatic float calc_humidity( uint16_t hum_adc, const struct bme680_dev *dev )\n{\n\tfloat calc_hum = 0;\n\tfloat var1 = 0;\n\tfloat var2 = 0;\n\tfloat var3 = 0;\n\tfloat var4 = 0;\n\tfloat temp_comp;\n\n\ttemp_comp  = ( ( dev->calib.t_fine ) / 5120.0f );\n\n\tvar1 = ( float )( ( float )hum_adc ) - ( ( ( float )dev->calib.par_h1 * 16.0f ) + ( ( ( float )dev->calib.par_h3 / 2.0f )\n\t        * temp_comp ) );\n\n\tvar2 = var1 * ( ( float )( ( ( float ) dev->calib.par_h2 / 262144.0f ) * ( 1.0f + ( ( ( float )dev->calib.par_h4 / 16384.0f )\n\t                           * temp_comp ) + ( ( ( float )dev->calib.par_h5 / 1048576.0f ) * temp_comp * temp_comp ) ) ) );\n\n\tvar3 = ( float ) dev->calib.par_h6 / 16384.0f;\n\n\tvar4 = ( float ) dev->calib.par_h7 / 2097152.0f;\n\n\tcalc_hum = var2 + ( ( var3 + ( var4 * temp_comp ) ) * var2 * var2 );\n\n\tif ( calc_hum > 100.0f )\n\t{\n\t\tcalc_hum = 100.0f;\n\t}\n\telse if ( calc_hum < 0.0f )\n\t{\n\t\tcalc_hum = 0.0f;\n\t}\n\n\treturn calc_hum;\n}\n\nstatic float calc_gas_resistance( uint16_t gas_res_adc, uint8_t gas_range, const struct bme680_dev *dev )\n{\n\tfloat calc_gas_res;\n\tfloat var1 = 0;\n\tfloat var2 = 0;\n\tfloat var3 = 0;\n\n\tconst float lookup_k1_range[16] =\n\t{\n\t\t0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -0.8,\n\t\t0.0, 0.0, -0.2, -0.5, 0.0, -1.0, 0.0, 0.0\n\t};\n\tconst float lookup_k2_range[16] =\n\t{\n\t\t0.0, 0.0, 0.0, 0.0, 0.1, 0.7, 0.0, -0.8,\n\t\t-0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0\n\t};\n\n\tvar1 = ( 1340.0f + ( 5.0f * dev->calib.range_sw_err ) );\n\tvar2 = ( var1 ) * ( 1.0f + lookup_k1_range[gas_range] / 100.0f );\n\tvar3 = 1.0f + ( lookup_k2_range[gas_range] / 100.0f );\n\n\tcalc_gas_res = 1.0f / ( float )( var3 * ( 0.000000125f ) * ( float )( 1 << gas_range ) * ( ( ( ( ( float )gas_res_adc )\n\t                                 - 512.0f ) / var2 ) + 1.0f ) );\n\n\treturn calc_gas_res;\n}\n\nstatic float calc_heater_res( uint16_t temp, const struct bme680_dev *dev )\n{\n\tfloat var1 = 0;\n\tfloat var2 = 0;\n\tfloat var3 = 0;\n\tfloat var4 = 0;\n\tfloat var5 = 0;\n\tfloat res_heat = 0;\n\n\tif ( temp > 400 )\n\t{\n\t\ttemp = 400;\n\t}\n\n\tvar1 = ( ( ( float )dev->calib.par_gh1 / ( 16.0f ) ) + 49.0f );\n\tvar2 = ( ( ( ( float )dev->calib.par_gh2 / ( 32768.0f ) ) * ( 0.0005f ) ) + 0.00235f );\n\tvar3 = ( ( float )dev->calib.par_gh3 / ( 1024.0f ) );\n\tvar4 = ( var1 * ( 1.0f + ( var2 * ( float )temp ) ) );\n\tvar5 = ( var4 + ( var3 * ( float )dev->amb_temp ) );\n\tres_heat = ( uint8_t )( 3.4f * ( ( var5 * ( 4 / ( 4 + ( float )dev->calib.res_heat_range ) ) *\n\t                                   ( 1 / ( 1 + ( ( float ) dev->calib.res_heat_val * 0.002f ) ) ) ) - 25 ) );\n\n\treturn res_heat;\n}\n\n#endif\n\nstatic uint8_t calc_heater_dur( uint16_t dur )\n{\n\tuint8_t factor = 0;\n\tuint8_t durval;\n\n\tif ( dur >= 0xfc0 )\n\t{\n\t\tdurval = 0xff; /* Max duration*/\n\t}\n\telse\n\t{\n\t\twhile ( dur > 0x3F )\n\t\t{\n\t\t\tdur = dur / 4;\n\t\t\tfactor += 1;\n\t\t}\n\n\t\tdurval = ( uint8_t ) ( dur + ( factor * 64 ) );\n\t}\n\n\treturn durval;\n}\n\nstatic int8_t read_field_data( struct bme680_field_data *data, struct bme680_dev *dev )\n{\n\tint8_t rslt;\n\tuint8_t buff[BME680_FIELD_LENGTH] = { 0 };\n\tuint8_t gas_range;\n\tuint32_t adc_temp;\n\tuint32_t adc_pres;\n\tuint16_t adc_hum;\n\tuint16_t adc_gas_res;\n\tuint8_t tries = 10;\n\n\trslt = null_ptr_check( dev );\n\n\tdo\n\t{\n\t\tif ( rslt == BME680_OK )\n\t\t{\n\t\t\trslt = bme680_get_regs( ( ( uint8_t ) ( BME680_FIELD0_ADDR ) ), buff, ( uint16_t ) BME680_FIELD_LENGTH,\n\t\t\t                        dev );\n\n\t\t\tdata->status = buff[0] & BME680_NEW_DATA_MSK;\n\t\t\tdata->gas_index = buff[0] & BME680_GAS_INDEX_MSK;\n\t\t\tdata->meas_index = buff[1];\n\n\t\t\tadc_pres = ( uint32_t ) ( ( ( uint32_t ) buff[2] * 4096 ) | ( ( uint32_t ) buff[3] * 16 )\n\t\t\t                          | ( ( uint32_t ) buff[4] / 16 ) );\n\t\t\tadc_temp = ( uint32_t ) ( ( ( uint32_t ) buff[5] * 4096 ) | ( ( uint32_t ) buff[6] * 16 )\n\t\t\t                          | ( ( uint32_t ) buff[7] / 16 ) );\n\t\t\tadc_hum = ( uint16_t ) ( ( ( uint32_t ) buff[8] * 256 ) | ( uint32_t ) buff[9] );\n\t\t\tadc_gas_res = ( uint16_t ) ( ( uint32_t ) buff[13] * 4 | ( ( ( uint32_t ) buff[14] ) / 64 ) );\n\t\t\tgas_range = buff[14] & BME680_GAS_RANGE_MSK;\n\n\t\t\tdata->status |= buff[14] & BME680_GASM_VALID_MSK;\n\t\t\tdata->status |= buff[14] & BME680_HEAT_STAB_MSK;\n\n\t\t\tif ( data->status & BME680_NEW_DATA_MSK )\n\t\t\t{\n\t\t\t\tdata->temperature = calc_temperature( adc_temp, dev );\n\t\t\t\tdata->pressure = calc_pressure( adc_pres, dev );\n\t\t\t\tdata->humidity = calc_humidity( adc_hum, dev );\n\t\t\t\tdata->gas_resistance = calc_gas_resistance( adc_gas_res, gas_range, dev );\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tdev->delay_ms( BME680_POLL_PERIOD_MS );\n\t\t}\n\n\t\ttries--;\n\t}\n\twhile ( tries );\n\n\tif ( !tries )\n\t{\n\t\trslt = BME680_W_NO_NEW_DATA;\n\t}\n\n\treturn rslt;\n}\n\nstatic int8_t set_mem_page( uint8_t reg_addr, struct bme680_dev *dev )\n{\n\tint8_t rslt;\n\tuint8_t reg;\n\tuint8_t mem_page;\n\n\trslt = null_ptr_check( dev );\n\n\tif ( rslt == BME680_OK )\n\t{\n\t\tif ( reg_addr > 0x7f )\n\t\t{\n\t\t\tmem_page = BME680_MEM_PAGE1;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tmem_page = BME680_MEM_PAGE0;\n\t\t}\n\n\t\tif ( mem_page != dev->mem_page )\n\t\t{\n\t\t\tdev->mem_page = mem_page;\n\n\t\t\tdev->com_rslt = dev->read( dev->dev_id, BME680_MEM_PAGE_ADDR | BME680_SPI_RD_MSK, &reg, 1 );\n\n\t\t\tif ( dev->com_rslt != 0 )\n\t\t\t{\n\t\t\t\trslt = BME680_E_COM_FAIL;\n\t\t\t}\n\n\t\t\tif ( rslt == BME680_OK )\n\t\t\t{\n\t\t\t\treg = reg & ( ~BME680_MEM_PAGE_MSK );\n\t\t\t\treg = reg | ( dev->mem_page & BME680_MEM_PAGE_MSK );\n\n\t\t\t\tdev->com_rslt = dev->write( dev->dev_id, BME680_MEM_PAGE_ADDR & BME680_SPI_WR_MSK,\n\t\t\t\t                            &reg, 1 );\n\n\t\t\t\tif ( dev->com_rslt != 0 )\n\t\t\t\t{\n\t\t\t\t\trslt = BME680_E_COM_FAIL;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn rslt;\n}\n\nstatic int8_t get_mem_page( struct bme680_dev *dev )\n{\n\tint8_t rslt;\n\tuint8_t reg;\n\n\trslt = null_ptr_check( dev );\n\n\tif ( rslt == BME680_OK )\n\t{\n\t\tdev->com_rslt = dev->read( dev->dev_id, BME680_MEM_PAGE_ADDR | BME680_SPI_RD_MSK, &reg, 1 );\n\n\t\tif ( dev->com_rslt != 0 )\n\t\t{\n\t\t\trslt = BME680_E_COM_FAIL;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tdev->mem_page = reg & BME680_MEM_PAGE_MSK;\n\t\t}\n\t}\n\n\treturn rslt;\n}\n\nstatic int8_t boundary_check( uint8_t *value, uint8_t min, uint8_t max, struct bme680_dev *dev )\n{\n\tint8_t rslt = BME680_OK;\n\n\tif ( value != NULL )\n\t{\n\t\tif ( *value < min )\n\t\t{\n\t\t\t*value = min;\n\t\t\tdev->info_msg |= BME680_I_MIN_CORRECTION;\n\t\t}\n\n\t\tif ( *value > max )\n\t\t{\n\t\t\t*value = max;\n\t\t\tdev->info_msg |= BME680_I_MAX_CORRECTION;\n\t\t}\n\t}\n\telse\n\t{\n\t\trslt = BME680_E_NULL_PTR;\n\t}\n\n\treturn rslt;\n}\n\nstatic int8_t null_ptr_check( const struct bme680_dev *dev )\n{\n\tint8_t rslt;\n\n\tif ( ( dev == NULL ) || ( dev->read == NULL ) || ( dev->write == NULL ) || ( dev->delay_ms == NULL ) )\n\t{\n\t\trslt = BME680_E_NULL_PTR;\n\t}\n\telse\n\t{\n\t\trslt = BME680_OK;\n\t}\n\n\treturn rslt;\n}\n"
              }
            }
          },
          "md5": "beec437787975a2dac4ad728546aab28"
        },
        "bhi160": {
          "libName": "bhi160",
          "manufacturer": "Bosch",
          "description": "Sensor Hub",
          "type": "Accelerometer Gyroscope",
          "icon": "",
          "image": "",
          "version": "",
          "eelVersion": "3",
          "shoppingCartLinks": {
            "digikey": {
              "links": {
                "info": "https://www.digikey.com/short/p905n3"
              },
              "cartData": {
                "part": "1471-1676-ND",
                "source": "dkstudio",
                "qty": "1"
              }
            }
          },
          "requires": [
            "embedded",
            "i2c",
            "gpio",
            "fpmath"
          ],
          "elements": [
            {
              "name": "EmbeddedBHI160",
              "type": "EmbeddedBHI160",
              "icon": "EmbeddedGyroscope.svg",
              "defaultAbility": "xAcceleration",
              "defaultTrigger": "xAccelerationRead",
              "hidden": false,
              "abilities": [
                {
                  "name": "setup",
                  "hidden": true,
                  "code": "    BHI160_Config_t config;\n    config.i2cInstance = ATMO_PROPERTY(undefined, i2cInstance);\n    config.gpioInstance = ATMO_PROPERTY(undefined, gpioInstance);\n    config.intPin = ATMO_PROPERTY(undefined, intPin);\n\n    if(!BHI160_Init(&config))\n    {\n        return ATMO_Status_Fail;\n    }\n    return ATMO_Status_Success;"
                },
                {
                  "name": "xAcceleration",
                  "triggers": [
                    "xAccelerationRead"
                  ],
                  "code": "    ATMO_3dFloatVector_t data;\n    BHI160_GetData(&data, NULL, NULL);\n    ATMO_CreateValueFloat(out, data.x);\n    return ATMO_Status_Success;"
                },
                {
                  "name": "yAcceleration",
                  "triggers": [
                    "yAccelerationRead"
                  ],
                  "code": "    ATMO_3dFloatVector_t data;\n    BHI160_GetData(&data, NULL, NULL);\n    ATMO_CreateValueFloat(out, data.y);\n    return ATMO_Status_Success;"
                },
                {
                  "name": "zAcceleration",
                  "triggers": [
                    "zAccelerationRead"
                  ],
                  "code": "    ATMO_3dFloatVector_t data;\n    BHI160_GetData(&data, NULL, NULL);\n    ATMO_CreateValueFloat(out, data.z);\n    return ATMO_Status_Success;"
                },
                {
                  "name": "acceleration",
                  "triggers": [
                    "accelerationRead"
                  ],
                  "code": "    ATMO_3dFloatVector_t data;\n    BHI160_GetData(&data, NULL, NULL);\n    ATMO_CreateValue3dVectorFloat(out, &data);\n    return ATMO_Status_Success;"
                },
                {
                  "name": "angularRate",
                  "triggers": [
                    "angularRateRead"
                  ],
                  "code": "    ATMO_3dFloatVector_t data;\n    BHI160_GetData(NULL, &data, NULL);\n    ATMO_CreateValue3dVectorFloat(out, &data);\n    return ATMO_Status_Success;"
                },
                {
                  "name": "xAngularRate",
                  "triggers": [
                    "xAngularRateRead"
                  ],
                  "code": "    ATMO_3dFloatVector_t data;\n    BHI160_GetData(NULL, &data, NULL);\n    ATMO_CreateValueFloat(out, data.x);\n    return ATMO_Status_Success;"
                },
                {
                  "name": "yAngularRate",
                  "triggers": [
                    "yAngularRateRead"
                  ],
                  "code": "    ATMO_3dFloatVector_t data;\n    BHI160_GetData(NULL, &data, NULL);\n    ATMO_CreateValueFloat(out, data.y);\n    return ATMO_Status_Success;"
                },
                {
                  "name": "zAngularRate",
                  "triggers": [
                    "zAngularRateRead"
                  ],
                  "code": "    ATMO_3dFloatVector_t data;\n    BHI160_GetData(NULL, &data, NULL);\n    ATMO_CreateValueFloat(out, data.z);\n    return ATMO_Status_Success;"
                },
                {
                  "name": "orientation",
                  "triggers": [
                    "orientationRead"
                  ],
                  "code": "    ATMO_3dFloatVector_t data;\n    BHI160_GetData(NULL, NULL, &data);\n    ATMO_CreateValue3dVectorFloat(out, &data);\n    return ATMO_Status_Success;"
                },
                {
                  "name": "xOrientation",
                  "triggers": [
                    "xOrientationRead"
                  ],
                  "code": "    ATMO_3dFloatVector_t data;\n    BHI160_GetData(NULL, NULL, &data);\n    ATMO_CreateValueFloat(out, data.x);\n    return ATMO_Status_Success;"
                },
                {
                  "name": "yOrientation",
                  "triggers": [
                    "yOrientationRead"
                  ],
                  "code": "    ATMO_3dFloatVector_t data;\n    BHI160_GetData(NULL, NULL, &data);\n    ATMO_CreateValueFloat(out, data.y);\n    return ATMO_Status_Success;"
                },
                {
                  "name": "zOrientation",
                  "triggers": [
                    "zOrientationRead"
                  ],
                  "code": "    ATMO_3dFloatVector_t data;\n    BHI160_GetData(NULL, NULL, &data);\n    ATMO_CreateValueFloat(out, data.z);\n    return ATMO_Status_Success;"
                }
              ],
              "properties": [
                {
                  "name": "i2cInstance",
                  "input": "driverInstance",
                  "driverType": "i2c"
                },
                {
                  "name": "gpioInstance",
                  "input": "driverInstance",
                  "driverType": "gpio"
                },
                {
                  "name": "intPin",
                  "input": "number",
                  "value": 9
                }
              ],
...

This file has been truncated, please download it to see its full contents.

Credits

Cris Thomas

Cris Thomas

24 projects • 92 followers
Electronics and Aerospace engineer with a dedicated history in Research and Development. https://www.linkedin.com/in/crisdeodates/
Jiss Joseph Thomas

Jiss Joseph Thomas

21 projects • 55 followers

Comments